我一直在寻找这个特定的案例,但没有找到。我有这个 XML,除了这三个元素之外还有其他元素,但它们无关紧要。相关元素有两个 namespace 附加到它。我想删除 xmlns:two 所以在输出中只有第一个 xmlns 存在。
<?xml version="1.0" encoding="UTF-8"?>
<Header>
<one:id xmlns:one="http://x.com/xsd/so"
xmlns:two="http://x.com/xsd/woa.xsd">555</one:id>
<one:protocolVersion xmlns:one="http://x.com/xsd/so"
xmlns:two="http://x.com/xsd/woa.xsd">2.0</one:protocolVersion>
<one:userId xmlns:one="http://x.com/xsd/so"
xmlns:two="http://x.com/xsd/woa.xsd">12345</one:userId>
</Header>
现在我想要的是删除 xmlns:two
<?xml version="1.0" encoding="UTF-8"?>
<Header>
<one:id xmlns:one="http://x.com/xsd/so">555</one:id>
<one:protocolVersion xmlns:one="http://x.com/xsd/so">2.0</one:protocolVersion>
<one:userId xmlns:one="http://x.com/xsd/so">12345</one:userId>
</Header>
我试过这样的事情,但它删除了错误的命名空间。它删除了前缀相同的命名空间。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:two="http://x.com/xsd/woa.xsd"
xmlns:one="http://x.com/xsd/so">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="one:id">
<xsl:element name="{local-name()}">
<xsl:copy-of select="namespace::*[not(. = namespace-uri(..))]"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
最佳答案
有很多事情会阻止它创建您所描述的结果:
在这里,您只复制元素不使用的命名空间,而不是它使用的命名空间:
<xsl:copy-of select="namespace::*[not(. = namespace-uri(..))]"/>
在这里,您将在空命名空间(无命名空间)中创建一个元素:
<xsl:element name="{local-name()}">
您已声明
one
和 two
XSLT 样式表根元素上的命名空间,这意味着它们将包含在输出文档的根元素中。为了获得您所描述的结果,您可以使用以下命令:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="one:*" xmlns:one="http://x.com/xsd/so" >
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
或者,您可以使用更通用的、与命名空间无关的方法:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<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:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这两者都会产生你所说的你想要的输出。
关于xml - 如何从 XML 元素中删除一个特定的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50986281/