通过 XSL 1.0 将 XML 文件排序为树结构

sort an XML file into a tree structure by XSL 1.0

我想将具有分散元素的 XML 文件转换为树结构 XML 文件。

如果菜单的 'identifier' 存在于输入 XML 文件中的另一个菜单项中,则应将菜单上下文复制到 'menu_list' 元素中输出 XML 文件。

任何人都可以帮助我如何使用 XSL1.0.

实现这一点

输入XML文件:

<input>
    <menu>
        <identifier>1</identifier>
        <items>
            <item>2</item>
            <item>3</item>
        </items>
    </menu>
    <menu>
        <identifier>2</identifier>
        <items>
            <item>21</item>
            <item>22</item>
        </items>
    </menu>
    <menu>
        <identifier>3</identifier>
        <items>
            <item>31</item>
            <item>32</item>
        </items>
    </menu>
    <menu>
        <identifier>21</identifier>
        <items>
            <item>211</item>
            <item>212</item>
        </items>
    </menu>
    <menu>
        <identifier>22</identifier>
        <items>
            <item>221</item>
            <item>222</item>
        </items>
    </menu>
    <menu>
        <identifier>31</identifier>
        <items>
            <item>311</item>
            <item>312</item>
        </items>
    </menu>
    <menu>
        <identifier>32</identifier>
        <items>
            <item>321</item>
            <item>322</item>
        </items>
    </menu>
</input>

输出XML文件:

<input>
    <menu>
        <identifier>1</identifier>
        <items>
            <item>2</item>
            <item>3</item>
        </items>
        <menu_list>
            <menu>
                <identifier>2</identifier>
                <items>
                    <item>21</item>
                    <item>22</item>
                </items>
                <menu_list>
                    <menu>
                        <identifier>21</identifier>
                        <items>
                            <item>211</item>
                            <item>212</item>
                        </items>
                    </menu>
                    <menu>
                        <identifier>22</identifier>
                        <items>
                            <item>221</item>
                            <item>222</item>
                        </items>
                    </menu>
                </menu_list>
            </menu>
            <menu>
                <identifier>3</identifier>
                <items>
                    <item>31</item>
                    <item>32</item>
                </items>
                <menu_list>
                    <menu>
                        <identifier>31</identifier>
                        <items>
                            <item>311</item>
                            <item>312</item>
                        </items>
                    </menu>
                    <menu>
                        <identifier>32</identifier>
                        <items>
                            <item>321</item>
                            <item>322</item>
                        </items>
                    </menu>
                </menu_list>
            </menu>
        </menu_list>
    </menu>
</input>

这样试试:

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="children" match="menu" use="identifier" />
<xsl:key name="parent" match="menu" use="items/item" />

<xsl:template match="/input">
    <xsl:copy>
        <xsl:apply-templates select="menu[not(key('parent', identifier))]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="menu">
    <xsl:copy>
        <xsl:copy-of select="*"/>
        <xsl:variable name="children" select="key('children', items/item)"/>
        <xsl:if test="$children">
            <menu_list>
                <xsl:apply-templates select="$children"/>
            </menu_list>
        </xsl:if>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>