使用 XSLT 基于路径选择 XML

Posted

技术标签:

【中文标题】使用 XSLT 基于路径选择 XML【英文标题】:Selecting XML based on Path using XSLT 【发布时间】:2020-01-18 00:59:29 【问题描述】:

我有一个源 xml,我想根据路径进行选择,即来自第二个或第三个 xml 节点。我尝试过使用 Some XSLT 代码,但没有得到准确的输出。

输入 XML:

            <?xml version="1.0" encoding="UTF-8"?>
            <ns0:Header xmlns:ns0="http://xyz987.com">
                <Main>
                    <Parent2>
                        <Parent2>
                            <?xml version="1.0" encoding="UTF-8"?>
                            <Child1>
                                <GChild1>12</GChild1>
                                <Child2>
                                    <GChild2>12</GChild2>
                                </Child2>
                            </Child1>
                        </Parent2>
                    </Parent2>

                </Main>
            </ns0:Header>

目标 XML:

            <?xml version="1.0" encoding="UTF-8"?>
            <Child1>
                <GChild1>12</GChild1>
                <Child2>
                    <GChild2>12</GChild2>
                </Child2>
            </Child1>

尝试过 XSLT 代码:

            <?xml version="1.0" encoding="UTF-8" ?>
            <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
                <xsl:output method="xml"  omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
                <xsl:strip-space elements="*"/>
                <xsl:template match="/">

                    <xsl:apply-templates select="/Header/Parent2/Parent2"/>

                </xsl:template>

                <xsl:template match="@*">
                    <xsl:copy>
                        <xsl:apply-templates select="@*"/>
                    </xsl:copy>
                </xsl:template>

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

            </xsl:transform>

【问题讨论】:

这真的是你的 XML,因为在 XML 文档中间有一个 &lt;?xml version="1.0" encoding="UTF-8"?&gt; 声明是无效的。它只能出现在第一行。或者,也许在您真正的 XML 中,它被包装在 CDATA 部分中,这将成为一个非常不同的问题!谢谢! 您的 Header 元素在命名空间中,而您的样式表正在寻找没有命名空间中的 Header 元素。, XSLT select nodes with namespace的可能重复 【参考方案1】:
**You can try this**:

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/">
        <xsl:apply-templates select="descendant::Parent2/Parent2/*"/>
    </xsl:template>
    <xsl:template match="*">
        <xsl:element name="local-name()">
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

输出为:

<?xml version="1.0" encoding="utf-8"?>
<Child1>
   <GChild1>12</GChild1>
   <Child2>
      <GChild2>12</GChild2>
   </Child2>
</Child1>

【讨论】:

【参考方案2】:

这个样式表会复制/Header/Main/Parent2/Parent2下的所有子节点:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ns0="http://xyz987.com">
    <xsl:output method="xml"  omit-xml-declaration="no" encoding="UTF-8" indent="yes" />
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:copy-of select="ns0:Header/Main/Parent2/Parent2/*"/>
    </xsl:template>
</xsl:transform>

输出:

<Child1 xmlns:ns0="http://xyz987.com">
   <GChild1>12</GChild1>
   <Child2>
      <GChild2>12</GChild2>
   </Child2>
</Child1>

【讨论】:

【参考方案3】:

仅检查以下代码:-

<xsl:template match="Header">
        <xsl:copy-of select="Main/Parent2/Parent2/*"/>
</xsl:template>

【讨论】:

以上是关于使用 XSLT 基于路径选择 XML的主要内容,如果未能解决你的问题,请参考以下文章

使用 XSLT 基于 ID 从多个 xPath 中选择 XML 节点

基于另一个变量的 XSLT 元素选择

使用 xslt 获取位于另一个路径中的另一个 xml 值

动态添加 XML 标记,并且不应该允许基于使用 XSLT 的 xml 中特定标记的计数重复

基于“名称”属性使用 XSLT 重命名 XML 节点

使用 XSLT 在选择字段中显示来自 XML 的数据