XSLT:将命名空间添加到根元素
Posted
技术标签:
【中文标题】XSLT:将命名空间添加到根元素【英文标题】:XSLT: Add namespace to root element 【发布时间】:2011-02-10 19:32:03 【问题描述】:我需要更改根元素中的命名空间,如下所示:
输入文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
xmlns:ns2="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
想要的输出:
<foo audience="external" xsi:schemaLocation="urn:isbn:1-931666-22-9
http://www.loc.gov/ead/ead.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9">
我在复制整个文档时尝试这样做,然后再给出任何其他转换说明,但以下方法不起作用:
<xsl:template match="* | processing-instruction() | comment()">
<xsl:copy copy-namespaces="no">
<xsl:for-each select=".">
<xsl:attribute name="audience" select="'external'"/>
<xsl:namespace name="xlink" select="'http://www.w3.org/1999/xlink'"/>
</xsl:for-each>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
感谢您的建议!
【问题讨论】:
好问题 (+1)。有关完整的 XSLT 1.0 和 2.0 解决方案,请参阅我的答案。 :) 【参考方案1】:XSLT 2.0 不是解决此问题所必需的。
这是一个 XSLT 1.0 解决方案,它与 XSLT 2.0 一样好用(只需将 version
属性更改为 2.0
):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="http://www.w3.org/1999/xlink"
exclude-result-prefixes="xlink"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:element name="name()" namespace="namespace-uri()">
<xsl:copy-of select=
"namespace::*
[not(name()='ns2')
and
not(name()='')
]"/>
<xsl:copy-of select=
"document('')/*/namespace::*[name()='xlink']"/>
<xsl:copy-of select="@*"/>
<xsl:attribute name="audience">external</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
当上述转换应用于此 XML 文档时:
<foo
xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
xmlns:ns2="http://www.w3.org/1999/xlink"
xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
产生想要的结果:
<foo xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
audience="external"/>
【讨论】:
谢谢!非常有帮助!omit-xml-declaration="yes"
对于生成格式良好的 html5 输出也很有用。【参考方案2】:
您确实应该为此使用“身份模板”,并且您应该随时准备好它。使用该模板创建一个 XSLT,将其命名为“identity.xslt”,然后进入当前的 XSLT。假设要替换的命名空间的前缀为“bad”,而要替换的命名空间为“good”with,那么你只需要一个这样的模板(我在工作,所以请原谅格式;当我在家时,我会回到这个问题):...如果这在 XSLT 1.0 中不起作用,请使用匹配表达式,如 "*[namespace-uri() = 'urn :bad-namespace'",并按照 Dimitre 的说明以编程方式创建新元素。在 内,您确实需要递归地应用模板……但实际上,请阅读身份模板。
【讨论】:
以上是关于XSLT:将命名空间添加到根元素的主要内容,如果未能解决你的问题,请参考以下文章