gpt4 book ai didi

xml - 删除命名空间并使用 XSL 提取 XML 文件的子集

转载 作者:数据小太阳 更新时间:2023-10-29 02:09:18 25 4
gpt4 key购买 nike

当我的输入 Xml 为:

 <country>
<state>
<city>
<name>DELHI</name>
</city>
</state>
</country>

所需的输出如下:

<city>
<name>DELHI</name>
</city

以下 xsl 工作正常:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:template match="/">
<xsl:copy-of select="//city">
</xsl:copy-of>
</xsl:template>
</xsl:stylesheet>

但相同的 XSL 不适用于上述输入 XML,如果添加了 namespace :像下面这样:

<country xmlns="http://india.com/states" version="1.0">
<state>
<city>
<name>DELHI</name>
</city>
</state>
</country>

我希望删除 namespace 以及复制城市元素。

如有任何帮助,我们将不胜感激。谢谢

最佳答案

这是关于 XPath、XML 和 XSLT 最多的常见问题解答。搜索“默认命名空间和 XPath 表达式”。

至于解决方案:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://india.com/states">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>


<xsl:template match="*[not(ancestor-or-self::x:city)]">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<country xmlns="http://india.com/states" version="1.0">
<state>
<city>
<name>DELHI</name>
</city>
</state>
</country>

产生了想要的结果:

<city>
<name>DELHI</name>
</city>

解释:

  1. 在 XPath 中,一个没有前缀的元素名总是被认为是在“无 namespace ”中。但是,所提供的 XML 文档中的每个元素名称都位于非空命名空间中(默认命名空间 "http://india.com/states")。因此,//city 不选择任何节点(因为 XML 文档中没有元素是没有 namespace 的),而 //x:city where x: 绑定(bind)到命名空间 "http://india.com/states" 选择所有城市元素(在命名空间"http://india.com/states ").

  2. 在这个转换中有两个模板。第一个模板匹配任何元素并重新创建它,但在无命名空间中。它还复制所有属性,然后将模板应用于该元素的子节点。

  3. 对于所有不是 city 元素的祖先元素或本身不是 city 元素的元素,第二个模板会覆盖第一个模板。这里的 Action 是在所有子节点上应用模板。

更新:OP 修改了询问为什么在处理新的、修改后的 XML 文档的结果中有不需要的文本的问题:

<country xmlns="http://india.com/states" version="1.0">
<state>
<city>
<name>DELHI</name>
</city>
</state>
<state2>
<city2>
<name2>MUMBAI</name2>
</city2>
</state2>
</country>

为了生成文本“MUMBAI”,上面的转换需要稍微修改——忽略(不是复制)任何没有x 的文本节点:城市 祖先。为此,我们添加了以下单行空模板:

 <xsl:template match="text()[not(ancestor::x:city)]"/>

整个转换现在变成了:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://india.com/states">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>

<xsl:template match="*[not(ancestor-or-self::x:city)]">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="text()[not(ancestor::x:city)]"/>
</xsl:stylesheet>

结果仍然是想要的,正确的:

<city>
<name>DELHI</name>
</city>

关于xml - 删除命名空间并使用 XSL 提取 XML 文件的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6575964/

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