使用XSLT从XSLT样式表中删除名称空间声明
我有一个类似于以下的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(),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:
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> (为了清晰起见,我调整了空白.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |