【发布时间】:2015-10-05 02:53:15
【问题描述】:
我有以下 XML:
<ns1:A xmlns:ns1="http://www.namespace1.com" xmlns:ns2="http://www.namespace2.com">
<B>
<C>123</C>
</B>
<ns2:D>
<E>456</E>
</ns2:D>
</ns1:A>
我想使用以下 XSLT 对其进行转换:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xsl xs xsi">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="@*|namespace::*[name()]"/>
<xsl:if test="text() != ''">
<xsl:value-of select="concat(text(), 'xyz')"/>
</xsl:if>
<xsl:apply-templates select="*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
输出包含元素 B 和 E 的不需要的空白命名空间:
<A xmlns="http://www.namespace1.com" xmlns:ns1="http://www.namespace1.com" xmlns:ns2="http://www.namespace2.com">
<B xmlns="">
<C>123xyz</C>
</B>
<D xmlns="http://www.namespace2.com">
<E xmlns="">456xyz</E>
</D>
</A>
我希望删除输出中的空白名称空间。我看过很多关于分配默认命名空间或将元素分配给某个父命名空间的帖子。然而,这不是我想要的。在输出中,我确实希望元素 B、C 和 E 保留在“空白”命名空间中,因为这是相应的 XSD 所需要的(由于遗留原因,我无法更新 XSD)。所以想要的输出是:
<A xmlns="http://www.namespace1.com" xmlns:ns1="http://www.namespace1.com" xmlns:ns2="http://www.namespace2.com">
<B>
<C>123xyz</C>
</B>
<D xmlns="http://www.namespace2.com">
<E>456xyz</E>
</D>
</A>
如何摆脱输出中的空白命名空间?我还想指出,XSLT 将应用于具有不同模式结构的不同输入 XML,因此 XSLT 必须尽可能通用,而不需要对元素或命名空间名称进行硬编码。
编辑:
查看 M. Kay 和 M. Hor 的答案后,我意识到我之前的“期望”输出是不正确的。正如 M. Hor 所解释的,默认命名空间是继承的,如我之前的“所需”输出中列出的那样,这也不是我想要的。 (对不起,不正确的“期望”输出)。
我(更正后)想要的输出是不使用任何默认命名空间,而是使用命名空间前缀:
<ns1:A xmlns:ns1="http://www.namespace1.com" xmlns:ns2="http://www.namespace2.com">
<B>
<C>123xyz</C>
</B>
<ns2:D>
<E>456xyz</E>
</ns2:D>
</ns1:A>
我已经更新了我的 XSLT 作为下面这个问题的答案,它输出了我想要的。
谢谢! IK
【问题讨论】:
标签: xml xslt namespaces