gpt4 book ai didi

xml - XSLT 删除空白命名空间而不将元素分配给不同的或默认命名空间

转载 作者:行者123 更新时间:2023-12-04 16:56:04 25 4
gpt4 key购买 nike

我有以下 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>

我的愿望是删除输出中的空白 namespace 。我看过很多关于分配默认 namespace 或将元素分配给某个父 namespace 的帖子。然而这不是我想要的。在输出中,我确实希望元素 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 必须尽可能通用,不要对元素或 namespace 名称进行硬编码。

编辑:

查看 M. Kay 和 M. Hor 的答案,我意识到我之前的“期望”输出不正确。正如 M. Hor 所解释的那样,默认命名空间是按照我之前的“期望”输出中列出的那样继承的,这也不是我想要的。 (抱歉不正确的“期望”输出)。

我(更正)所需的输出是不使用任何默认 namespace ,而是使用 namespace 前缀:
<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 作为下面这个问题的答案,它输出了我想要的。

谢谢!
我知道

最佳答案

(The input and output is the same only because I am using a simplified XSLT for now).



当您的 XSLT 实际上没有改变任何东西时,就很难理解问题所在。对于声明的目的, identity transform 模板应该可以正常工作:
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="2.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

编辑

响应您的编辑,显示不同的所需输出:

你说:

I do want elements B,C, and E to remain in the "blank" namespace



但那是 而不是 在您想要的输出中会发生什么:
<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>

在这里,元素 BC 从它们的 A 祖先继承了它们的命名空间。类似地, E 元素与其 D 父元素位于相同的命名空间中。

这就是声明默认命名空间时的工作方式:声明范围内的所有元素都放置在该命名空间中。为了将 B 放在无命名空间中,您必须明确异常(exception)。这就是您在实际结果中看到 <B xmlns=""> 的原因。

关于xml - XSLT 删除空白命名空间而不将元素分配给不同的或默认命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31441017/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com