通过 XSL1.0 转换 XML 文件
transform an XML file by XSL1.0
我想根据菜单的'identifier'和'items'元素修改一个XML文件。
如果一个菜单的 'identifier' 存在于输入 XML 文件中的另一个菜单项中,则菜单上下文应复制到输出 [=45] 中的父菜单下方=] 文件,顺序应与父项目相同。
菜单元素'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>
我想根据菜单的'identifier'和'items'元素修改一个XML文件。
如果一个菜单的 'identifier' 存在于输入 XML 文件中的另一个菜单项中,则菜单上下文应复制到输出 [=45] 中的父菜单下方=] 文件,顺序应与父项目相同。
菜单元素'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>