【问题标题】:Converting a flat xml to a tree hierarchy based on IDs of inner elements根据内部元素的 ID 将平面 xml 转换为树层次结构
【发布时间】:2021-12-22 22:15:39
【问题描述】:

我的起始 XML 包含一个无序的平面目录列表,其中包含一个元素,每个元素都有自己的 ID 和子 ID(如果有的话)。

我的起始 XML 如下所示:

<root>

<catalogue>
    <item>
        <id>item2</id>
        <child>
            <id>item3</id>
        </child>
    </item>
</catalogue>

<catalogue>
    <item>
        <id>item1</id>
        <child>
            <id>item2</id>
        </child>
    </item>
</catalogue>

<catalogue>
    <item>
        <id>item3</id>
    </item>
</catalogue>

</root>

我需要将其转换为嵌套的树层次结构,其中相应的子项写入其父项内。

生成的 XML 应如下所示:

<root>

<catalogue>
    <item>
        <id>item1</id>
        <child>
            <id>item2</id>
        </child>
    </item>
    <catalogue>
        <item>
            <id>item2</id>
            <child>
                <id>item3</id>
            </child>
        </item>
        <catalogue>
            <item>
                <id>item3</id>
            </item>
        </catalogue>
    </catalogue>
</catalogue>

</root>

我已经有点接近解决方案了,但我无法让生成的 XML 文件不包含不必要的重复元素。

在以下 XML 文件中,根目录中的顶部和底部目录是重复的不需要的条目。我只需要大而中等的目录。

我当前的结果 XML 如下所示:

<root>

<catalogue>
    <item>
        <id>item2</id>
        <child>
            <id>item3</id>
        </child>
    </item>
    <catalogue>
        <item>
            <id>item3</id>
        </item>
    </catalogue>
</catalogue>

<catalogue>
    <item>
        <id>item1</id>
        <child>
            <id>item2</id>
        </child>
    </item>
    <catalogue>
        <item>
            <id>item2</id>
            <child>
                <id>item3</id>
            </child>
        </item>
        <catalogue>
            <item>
                <id>item3</id>
            </item>
        </catalogue>
    </catalogue>
</catalogue>

<catalogue>
    <item>
        <id>item3</id>
    </item>
</catalogue>

</root>

正在使用此 XSLT 文件创建我当前的结果 XML:

<xsl:stylesheet     version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="catalogue">
    <xsl:copy>
        <xsl:apply-templates select="node() | @*"/>
        <xsl:for-each select="/root/catalogue[item/id/text() = current()/item/child/id/text()]">
            <xsl:apply-templates select="."/>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

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

</xsl:stylesheet>

我一直试图找到解决这个问题的方法太久了,所以我希望有人能帮助我。

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    可能是这样的:

    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="*"/>
    
    <xsl:key name="cat" match="catalogue" use="item/id" />
    
    <xsl:template match="/root">
        <xsl:copy>
            <!-- start with items that are not children of any item -->
            <xsl:apply-templates select="catalogue[not(item/id = //child/id)]"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="catalogue">
        <xsl:copy>
            <xsl:copy-of select="item"/>
            <!-- recurse with current item's children -->
            <xsl:apply-templates select="key('cat', item/child/id)"/>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-06
      • 2018-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-08
      • 1970-01-01
      • 2022-07-15
      相关资源
      最近更新 更多