如何用内联 xmlns 声明替换 XML 名称空间前缀?
How can I replace XML namespace prefixes with inline xmlns declarations?
我有两个 XML 对象,我认为它们描述了同一个实体,一个使用命名空间前缀,一个使用内联命名空间声明。我想区分它们,但是表示命名空间的不同方式使这几乎不可能。
如何获取下面的第一个 xml 代码段并将其更改为与第二个代码段匹配?
<!--I want to take data that looks like this-->
<Foo xmlns:e="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">
<e:Description></e:Description>
<e:Name i:nil="true"></e:Name>
<e:DisplaySeqNo>0</e:DisplaySeqNo>
</Foo>
<!--I want to make that data that looks like this-->
<Foo>
<Description xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo"></Description>
<Name i:nil="true" xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo"></Name>
<DisplaySeqNo xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">0</DisplaySeqNo>
</Foo>
区分它们的要求是手动调试过程的一部分,因此我很乐意使用网络工具、脚本或其他任何工具。我不打算定期这样做,但我正在努力弄清楚 xml 样本 A 与 xml 样本 B 有何不同。
您可以使用以下 XSLT-1.0 样式表。它是 Identity 模板(复制所有节点)与处理替换情况的两个模板的组合:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:e="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">
<xsl:output method="xml" indent="yes"/>
<!-- Identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Foo">
<xsl:element name="{local-name()}" namespace="">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
<xsl:template match="e:*">
<xsl:element name="{local-name()}" namespace="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
它的输出是:
<Foo>
<Description xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo"/>
<Name xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo" i:nil="true"/>
<DisplaySeqNo xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">0</DisplaySeqNo>
</Foo>
它还会为 XML 文件生成错误,因为其中未定义 i
命名空间。它还从输入 XML 中复制注释,但我想这只是用于说明的注释,因此可以忽略。
如果您使用某种 Linux,您可以轻松地将此模板传递给 xsltproc
。
我有两个 XML 对象,我认为它们描述了同一个实体,一个使用命名空间前缀,一个使用内联命名空间声明。我想区分它们,但是表示命名空间的不同方式使这几乎不可能。
如何获取下面的第一个 xml 代码段并将其更改为与第二个代码段匹配?
<!--I want to take data that looks like this-->
<Foo xmlns:e="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">
<e:Description></e:Description>
<e:Name i:nil="true"></e:Name>
<e:DisplaySeqNo>0</e:DisplaySeqNo>
</Foo>
<!--I want to make that data that looks like this-->
<Foo>
<Description xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo"></Description>
<Name i:nil="true" xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo"></Name>
<DisplaySeqNo xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">0</DisplaySeqNo>
</Foo>
区分它们的要求是手动调试过程的一部分,因此我很乐意使用网络工具、脚本或其他任何工具。我不打算定期这样做,但我正在努力弄清楚 xml 样本 A 与 xml 样本 B 有何不同。
您可以使用以下 XSLT-1.0 样式表。它是 Identity 模板(复制所有节点)与处理替换情况的两个模板的组合:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:e="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">
<xsl:output method="xml" indent="yes"/>
<!-- Identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Foo">
<xsl:element name="{local-name()}" namespace="">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
<xsl:template match="e:*">
<xsl:element name="{local-name()}" namespace="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
它的输出是:
<Foo>
<Description xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo"/>
<Name xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo" i:nil="true"/>
<DisplaySeqNo xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">0</DisplaySeqNo>
</Foo>
它还会为 XML 文件生成错误,因为其中未定义 i
命名空间。它还从输入 XML 中复制注释,但我想这只是用于说明的注释,因此可以忽略。
如果您使用某种 Linux,您可以轻松地将此模板传递给 xsltproc
。