在根元素上用 XSLT 替换多个命名空间
我有以下 XML 文档
<a:rootElement xmlns:a="http://a/1" xmlns:b="http://b/1" xmlns:c="http://c/1">
<child1 type="b:type"/>
<child2 type="c:type"/>
</a:rootElement>
现在我想更改命名空间的 URI,以便得到以下结果
<a:rootElement xmlns:a="http://a/2" xmlns:b="http://b/2" xmlns:c="http://c/2">
<child1 type="b:type"/>
<child2 type="c:type"/>
</a:rootElement>
其他内容不应更改。我用下面的样式表尝试了它。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:a="http://a/2"
xmlns:b="http://b/2"
xmlns:c="http://c/2" >
<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:copy-of select="document('')/*/namespace::*[name()='a']"/>
<xsl:copy-of select="document('')/*/namespace::*[name()='b']"/>
<xsl:copy-of select="document('')/*/namespace::*[name()='c']"/>
<xsl:copy-of select="node()|@*"/>
</xsl:element>
</xsl:template>
我得到以下错误的输出。
<a_0:rootElement xmlns:a_0="http://a/1" xmlns:a="http://a/2" xmlns:b="http://b/2" xmlns:c="http://c/2">
<child1 type="b:type" xmlns:a="http://a/1" xmlns:b="http://b/1" xmlns:c="http://c/1"/>
<child2 type="c:type" xmlns:a="http://a/1" xmlns:b="http://b/1" xmlns:c="http://c/1"/>
</a_0:rootElement>
我也尝试了其他一些方法,但也没有得到所需的输出。是否有可能使用 XSLT 以这种方式更改名称空间?
感谢您的任何建议
I have the following XML document
<a:rootElement xmlns:a="http://a/1" xmlns:b="http://b/1" xmlns:c="http://c/1">
<child1 type="b:type"/>
<child2 type="c:type"/>
</a:rootElement>
Now I want to change the URIs of the namespaces so I get the following result
<a:rootElement xmlns:a="http://a/2" xmlns:b="http://b/2" xmlns:c="http://c/2">
<child1 type="b:type"/>
<child2 type="c:type"/>
</a:rootElement>
Nothing else should change. I tried it with the following stylesheet.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:a="http://a/2"
xmlns:b="http://b/2"
xmlns:c="http://c/2" >
<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:copy-of select="document('')/*/namespace::*[name()='a']"/>
<xsl:copy-of select="document('')/*/namespace::*[name()='b']"/>
<xsl:copy-of select="document('')/*/namespace::*[name()='c']"/>
<xsl:copy-of select="node()|@*"/>
</xsl:element>
</xsl:template>
I get the following wrong output.
<a_0:rootElement xmlns:a_0="http://a/1" xmlns:a="http://a/2" xmlns:b="http://b/2" xmlns:c="http://c/2">
<child1 type="b:type" xmlns:a="http://a/1" xmlns:b="http://b/1" xmlns:c="http://c/1"/>
<child2 type="c:type" xmlns:a="http://a/1" xmlns:b="http://b/1" xmlns:c="http://c/1"/>
</a_0:rootElement>
I tried a few other ways too but also without the desired output. Is it even possible to change the namespaces in this way with XSLT?
Thanks for any advice
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
此转换:
应用于提供的 XML 文档时:
产生所需的正确结果:
This transformation:
when applied on the provided XML document:
produces the wanted, correct result:
我认为 Dimitre 充分证明了我的观点,即任何 XSLT 解决方案都比在使用 XSLT 处理 XML 文档之前简单地在 XML 文档的第一行上进行文本替换要复杂得多。
不同命名空间的元素在技术上是完全不同的元素。因为 XML 技术认为它们是不同的,所以您实际上必须处理每一个,即使它们在输出时看起来是相同的。
具体如何操作取决于您所使用的平台,但只需简单地“查找第一次出现的
http://a/1
并将其替换为http://a/ 2
应该为每个命名空间完成这项工作。I think Dimitre adequately proved my point that any XSLT solution is going to be a lot more complicated than simply doing a text-replace on the first line of your XML document before processing it with XSLT.
Elements of different namespaces are technically completely different elements. Because XML technology considers them to be different, you actually have to handle and process each one, even though they'll appear identical when output.
Exactly how you do it depends on the platform you're using, but a simple 'find the first occurrence of
http://a/1
and replace it withhttp://a/2
should do the job, for each namespace.