<?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(),string(@id),-1)"/> <root> <xsl:apply-templates /> </root> </xsl:template> <!-- Other stuff --> </xsl:stylesheet>
我想使用第二个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>
输出:
<?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>
exclude-result-prefixes="foo"
到你的
<xsl:stylesheet>
元件.然后,如果可能,将省略foo的名称空间声明,即如果该名称空间中没有要输出的元素或属性.
仅供参考,原因是这条线
<xsl:template match="xsl:stylesheet/@xmlns:foo" />`
抛出错误是因为输入文档中的xmlns:foo不是属性;这是一个伪属性.您的匹配模式要求匹配的是名为foo的属性,该属性位于与命名空间前缀xmlns对应的命名空间中.由于尚未在样式表中声明名称空间前缀xmlns,因此会出现错误“未定义前缀xmlns”.
更新:
我从你发布的输出(以及我自己的测试)中看到,exclude-result-prefixes在删除命名空间声明时没有效果.
1)首先我会问为什么这很重要.它不会更改输出XSLT中任何内容的命名空间.你是否只是出于审美原因试图将其删除?
2)查看XSLT 1.0 spec,it appears to me< xsl:copy>不关注exclude-result-prefixes:
Instantiating the xsl:copy element creates a copy of the current node.
The namespace nodes of the current node are automatically copied as
well…
AFAICT,只有文字结果元素将基于exclude-result-prefixs省略命名空间节点.
在此基础上,我会尝试替换< 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>
这给了我认为是理想的输出,没有多余的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>
(为了清晰起见,我调整了空白.)