通过 XSL1.0 转换 XML 文件

transform an XML file by XSL1.0

我想根据菜单的'identifier'和'items'元素修改一个XML文件。

  1. 如果一个菜单的 'identifier' 存在于输入 XML 文件中的另一个菜单项中,则菜单上下文应复制到输出 [=45] 中的父菜单下方=] 文件,顺序应与父项目相同。

  2. 菜单元素'label'改为'level_xx'。'xx'为层数,详见excel截图.

任何人都可以帮助我如何使用 XSL1.0 实现这一目标。

输入XML文件:

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

输出XML文件:

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

the level info of the output

假设您的输入 XML 实际上是这样的:

XML

<input>
    <menu>
        <identifier>1</identifier>
        <label>"1"</label>
        <items>
            <item>2</item>
            <item>3</item>
        </items>
    </menu>
    <menu>
        <identifier>2</identifier>
        <label>"2"</label>
        <items>
            <item>21</item>
            <item>22</item>
        </items>
    </menu>
    <menu>
        <identifier>3</identifier>
        <label>"3"</label>
        <items>
            <item>31</item>
            <item>32</item>
        </items>
    </menu>
    <menu>
        <identifier>21</identifier>
        <label>"21"</label>
        <items>
            <item>211</item>
            <item>212</item>
        </items>
    </menu>
    <menu>
        <identifier>22</identifier>
        <label>"22"</label>
        <items>
            <item>221</item>
            <item>222</item>
        </items>
    </menu>
    <menu>
        <identifier>31</identifier>
        <label>"31"</label>
        <items>
            <item>311</item>
            <item>312</item>
        </items>
    </menu>
    <menu>
        <identifier>32</identifier>
        <label>"32"</label>
        <items>
            <item>321</item>
            <item>322</item>
        </items>
    </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:with-param name="level" select="1"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

<xsl:template match="menu">
    <xsl:param name="level"/>
    <xsl:copy>
        <xsl:copy-of select="identifier"/>
        <xsl:element name="level_{format-number($level, '00')}">
            <xsl:value-of select="label" />
        </xsl:element>
        <xsl:copy-of select="items"/>
    </xsl:copy>
    <xsl:apply-templates select="key('children', items/item)">
        <xsl:with-param name="level" select="$level + 1"/>
    </xsl:apply-templates>
</xsl:template>

</xsl:stylesheet>

已添加:

如果您需要子 menu 元素以与 item 元素在 items 中相同的顺序列出,则更改此部分:

    <xsl:apply-templates select="key('children', items/item)">
        <xsl:with-param name="level" select="$level + 1"/>
    </xsl:apply-templates>

至:

    <xsl:for-each select="items/item">
        <xsl:apply-templates select="key('children', .)">
            <xsl:with-param name="level" select="$level + 1"/>
        </xsl:apply-templates>
    </xsl:for-each>