Svi*_*ish 4 xslt xml-namespaces xslt-1.0
我有一个XSLT样式表,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:XQHeaderFunc="java:com.sonicsw.xq.service.xform.HeaderExtension"
xmlns:saxon="http://saxon.sf.net/">
<saxon:script language="java" implements-prefix="XQHeaderFunc" src="java:com.sonicsw.xq.service.xform.HeaderExtension" />
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:variable name="processId" select="XQHeaderFunc:getProperty(XQHeaderFunc:new(),'processId',-1)" />
<xsl:value-of select="XQHeaderFunc:setProperty(XQHeaderFunc:new(),'processId',string(@id),-1)"/>
<root>
<xsl:apply-templates />
</root>
</xsl:template>
<!-- Other stuff -->
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
我想使用第二个XSLT样式表来转换此样式表,以删除与XQHeaderFunc和saxon命名空间有关的任何内容.有没有办法可以做到这一点?
我现在尝试了以下,成功处理元素,但命名空间声明似乎不想消失.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:XQHeaderFunc="java:com.sonicsw.xq.service.xform.HeaderExtension"
xmlns:saxon="http://saxon.sf.net/"
exclude-result-prefixes="XQHeaderFunc saxon">
<xsl:param name="XQHeaderReplacement" />
<xsl:variable name="apos">'</xsl:variable>
<!-- Copy all nodes -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- Remove saxon script tag -->
<xsl:template match="saxon:script" />
<!-- Remove elements with setProperty calls -->
<xsl:template match="*[starts-with(@select, 'XQHeaderFunc:setProperty')]" />
<!-- Replace getProperty calls with replacement value-->
<xsl:template match="@select[starts-with(., 'XQHeaderFunc:getProperty')]">
<xsl:attribute name="select">
<xsl:value-of select="concat($apos, $XQHeaderReplacement, $apos)"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
输出:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:XQHeaderFunc="java:com.sonicsw.xq.service.xform.HeaderExtension"
xmlns:saxon="http://saxon.sf.net/">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:template match="/">
<xsl:variable name="processId" select="''" />
<root>
<xsl:apply-templates />
</root>
</xsl:template>
<!-- Other stuff -->
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
Lar*_*rsH 10
我想补充一下
exclude-result-prefixes="foo"
Run Code Online (Sandbox Code Playgroud)
到你的
<xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
元件.然后,foo如果可能,将省略名称空间声明,即如果该名称空间中没有要输出的元素或属性.
仅供参考,原因是这条线
<xsl:template match="xsl:stylesheet/@xmlns:foo" />`
Run Code Online (Sandbox Code Playgroud)
抛出错误是因为xmlns:foo在输入文档中不是属性; 这是一个伪属性.您的匹配模式要求匹配的是名称的属性foo,该属性位于与命名空间前缀对应的命名空间中xmlns.由于您尚未xmlns在样式表中声明名称空间前缀,因此会收到错误"未定义前缀xmlns".
我从你发布的输出(以及我自己的测试)中看到,exclude-result-prefixes它在删除命名空间声明方面没有效果.
1)首先我会问为什么这很重要.它不会更改输出XSLT中任何内容的命名空间.您是否只是出于美观原因试图将其删除?
2)看看XSLT 1.0规范,在我看来,<xsl:copy>不关注exclude-result-prefixes:
实例化xsl:copy元素会创建当前节点的副本.当前节点的命名空间节点也会自动复制......
AFAICT,只有文字结果元素会省略基于的命名空间节点exclude-result-prefixes.
在此基础上,我会尝试用<xsl:copy>您的身份模板(对于元素)替换<xsl:element name="{name()}">或使用其中的一些变体.然后,您需要为非元素节点使用单独的标识模板.
我用以下两个模板替换了您的身份模板:
<!-- Copy elements -->
<xsl:template match="*" priority="-1">
<xsl:element name="{name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<!-- Copy all other nodes -->
<xsl:template match="node()|@*" priority="-2">
<xsl:copy />
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
这给了我认为是理想的输出,没有多余的ns声明:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:template match="/">
<xsl:variable name="processId" select="''" />
<root>
<xsl:apply-templates />
</root>
</xsl:template>
<!-- Other stuff -->
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
(为了清晰起见,我调整了空白.)