用于删除或更改 xml 文档上的空 xmlns 的 XSL
XSL for removing or changing empty xmlns on xml document
一个同步 SOAP Web 服务正在用一个 xml 文档来回答我的请求,该文档有一个带有空 xmlns 属性 (<element xmlns="">value</element>
) 的元素。这当然会扰乱负责处理此响应的程序。
我想应用 XSL 转换来摆脱空 xmlns 或将其更改为正确的命名空间。
到目前为止,我在这里或其他网站上找到的 XSL 样式表不起作用,或者使固定元素的子元素现在有一个空的 xmlns。
我输入的xml文档如下:
<?xml version="1.0" encoding="utf-8"?>
<rootElement xmlns="http://tempuri.org/">
<level1>
<level2 xmlns="">
<child1 id="aNumber" desc="aString">
<name>name1</name>
<code>code1</code>
</child1>
<child2 desc="aString">
<field1>field1</field1>
<field2>field2</field2>
</child2>
</level2>
</level1>
</rootElement>
到目前为止,我使用此处找到的一些 xsl 样式表得到的最佳输出结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<rootElement xmlns="http://tempuri.org/">
<level1>
<level2>
<child1 xmlns="" desc="aString" id="aNumber">
<name>name1</name>
<code>code1</code>
</child1>
<child2 xmlns="" desc="aString">
<field1>field1</field1>
<field2>field2</field2>
</child2>
</level2>
</level1>
</rootElement>
level2 已修复,但现在 child1 和 child 2 各有一个空的 xmlns。这也使我的程序失败。
到目前为止,让我受益的最好和最简单的样式表是这个:
<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns="http://tempuri.org/">
<xsl:output encoding='UTF-8' indent='yes' method='xml'/>
<!-- copy everything into the output -->
<xsl:template match='@*|node()'>
<xsl:copy>
<xsl:apply-templates select='@*|node()'/>
</xsl:copy>
</xsl:template>
<!-- change the namespace declaration for level2 -->
<xsl:template match="level2">
<level2 xmlns='http://tempuri.org/'>
<xsl:copy-of select="@*|node()"/>
</level2>
</xsl:template>
</xsl:stylesheet>
to get rid of the empty xmlns or changing it to the proper namespace.
除了将无命名空间中的元素移动到与其 parent/ancestor 元素相同的命名空间外,没有其他方法可以“摆脱空的 xmlns”:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.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:template match="*[not(namespace-uri(.))]">
<xsl:element name="{local-name()}" namespace="http://tempuri.org/">
<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 method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
然而,这两种解决方案都存在缺陷;人们必须假设名称空间存在是有充分理由的。消除 <elem xmlns="http://tempuri.org/">
和 <elem>
之间的差异可能会产生意想不到的结果。
一个同步 SOAP Web 服务正在用一个 xml 文档来回答我的请求,该文档有一个带有空 xmlns 属性 (<element xmlns="">value</element>
) 的元素。这当然会扰乱负责处理此响应的程序。
我想应用 XSL 转换来摆脱空 xmlns 或将其更改为正确的命名空间。 到目前为止,我在这里或其他网站上找到的 XSL 样式表不起作用,或者使固定元素的子元素现在有一个空的 xmlns。 我输入的xml文档如下:
<?xml version="1.0" encoding="utf-8"?>
<rootElement xmlns="http://tempuri.org/">
<level1>
<level2 xmlns="">
<child1 id="aNumber" desc="aString">
<name>name1</name>
<code>code1</code>
</child1>
<child2 desc="aString">
<field1>field1</field1>
<field2>field2</field2>
</child2>
</level2>
</level1>
</rootElement>
到目前为止,我使用此处找到的一些 xsl 样式表得到的最佳输出结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<rootElement xmlns="http://tempuri.org/">
<level1>
<level2>
<child1 xmlns="" desc="aString" id="aNumber">
<name>name1</name>
<code>code1</code>
</child1>
<child2 xmlns="" desc="aString">
<field1>field1</field1>
<field2>field2</field2>
</child2>
</level2>
</level1>
</rootElement>
level2 已修复,但现在 child1 和 child 2 各有一个空的 xmlns。这也使我的程序失败。 到目前为止,让我受益的最好和最简单的样式表是这个:
<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns="http://tempuri.org/">
<xsl:output encoding='UTF-8' indent='yes' method='xml'/>
<!-- copy everything into the output -->
<xsl:template match='@*|node()'>
<xsl:copy>
<xsl:apply-templates select='@*|node()'/>
</xsl:copy>
</xsl:template>
<!-- change the namespace declaration for level2 -->
<xsl:template match="level2">
<level2 xmlns='http://tempuri.org/'>
<xsl:copy-of select="@*|node()"/>
</level2>
</xsl:template>
</xsl:stylesheet>
to get rid of the empty xmlns or changing it to the proper namespace.
除了将无命名空间中的元素移动到与其 parent/ancestor 元素相同的命名空间外,没有其他方法可以“摆脱空的 xmlns”:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.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:template match="*[not(namespace-uri(.))]">
<xsl:element name="{local-name()}" namespace="http://tempuri.org/">
<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 method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
然而,这两种解决方案都存在缺陷;人们必须假设名称空间存在是有充分理由的。消除 <elem xmlns="http://tempuri.org/">
和 <elem>
之间的差异可能会产生意想不到的结果。