我有按顺序排列的许多列表的xml。但我需要将所有列表序列转换为嵌套级别。下面我提到了输入和预期输出。请任何人尝试。
输入
<body>
<p>
<list level="1" type="normal">
<li id="(1)"> A </li>
<li id="(2)"> B </li>
</list>
<list level="2">
<li id="(a)">is</li>
<li id="(b)">was</li>
<li id="(c)">other market</li>
</list>
<list level="3">
<li id="(1)">first</li>
<li id="(2)">second</li>
<li id="(3)">third</li>
</list>
</p>
<sec>
<list level="1" type="normal">
<li id="(1)"> A </li>
</list>
<list level="2">
<li id="(a)">is</li>
<li id="(b)">was</li>
<li id="(c)">other market</li>
</list>
</sec>
</body>
预期输出
<?xml version="1.0" encoding="UTF-8"?>
<body>
<p>
<list level="1" type="normal">
<li id="(1)"> A </li>
<li id="(2)"> B <list level="2">
<li id="(a)">is</li>
<li id="(b)">was</li>
<li id="(c)">other market <list level="3">
<li id="(1)">first</li>
<li id="(2)">second</li>
<li id="(3)">third</li>
</list>
</li>
</list>
</li>
</list>
</p>
<sec>
<list level="1" type="normal">
<li id="(1)"> A <list level="2">
<li id="(a)">is</li>
<li id="(b)">was</li>
<li id="(c)">other market</li>
</list>
</li>
</list>
</sec>
</body>
任何人都请帮助我
我已经详细添加了一个输入。主要逻辑是根据级别属性的值对列表进行分组。
<?xml version="1.0" encoding="UTF-8"?>
<body>
<p>
<list level="1" type="normal">
<li id="(1)"> A </li>
<li id="(2)"> B </li>
</list>
<list level="2">
<li id="(a)">is</li>
<li id="(b)">was</li>
</list>
<list level="3">
<li id="(1)">first</li>
<li id="(2)">second</li>
</list>
<list level="2">
<li id="(c)">ff</li>
<li id="(d)">sss</li>
</list>
<list level="1">
<li id="(3)">C</li>
<li id="(4)">D</li>
</list>
</p>
<sec>
<list level="1" type="normal">
<li id="(1)"> A </li>
</list>
<list level="2">
<li id="(a)">is</li>
<li id="(b)">was</li>
<li id="(c)">other market</li>
</list>
</sec>
</body>
预期的输出是。
<?xml version="1.0" encoding="UTF-8"?>
<body>
<p>
<list level="1" type="normal">
<li id="(1)"> A </li>
<li id="(2)"> B <list level="2">
<li id="(a)">is</li>
<li id="(b)">was<list level="3">
<li id="(1)">first</li>
<li id="(2)">second</li></list></li>
<li id="(c)">ff</li>
<li id="(d)">sss</li>
</list></li>
<li id="(3)">C</li>
<li id="(4)">D</li>
</list>
</p>
<sec>
<list level="1" type="normal">
<li id="(1)"> A <list level="2">
<li id="(a)">is</li>
<li id="(b)">was</li>
<li id="(c)">other market</li>
</list></li>
</list>
</sec>
</body>
答案 0 :(得分:1)
首先从身份模板开始......
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
这至少会带你到中途!
您需要进行的转换之一是p
和sec
元素应该只有一个孩子; level1的list
元素,因此可以使用另一个模板
<xsl:template match="*[list]">
<xsl:copy>
<xsl:apply-templates select="list[@level='1']"/>
</xsl:copy>
</xsl:template>
然后,您只需要一个模板来匹配li
中的最后一个list
,然后复制它,并在孩提时修改以下list
。
<xsl:template match="li[not(following-sibling::*)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="../following-sibling::list[1]" />
</xsl:copy>
</xsl:template>
完全放下这个......
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="*[list]">
<xsl:copy>
<xsl:apply-templates select="list[@level='1']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="li[not(following-sibling::*)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="../following-sibling::list[1]" />
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这确实假设您没有多个列表,每个项目下都有相同的levelid
。
编辑:如果您有多个具有相同levelid
的列表项,则会变得有点复杂,但请尝试使用此XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="list" match="list" use="concat(generate-id(..), generate-id(preceding-sibling::list[@level = current()/@level - 1][1]))" />
<xsl:template match="*[list]">
<xsl:copy>
<xsl:apply-templates select="list[@level='1'][1]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="li[not(following-sibling::*)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="key('list', concat(generate-id(../..), generate-id(..)))[1]" />
</xsl:copy>
</xsl:template>
<xsl:template match="list">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="key('list', concat(generate-id(..), generate-id(preceding-sibling::list[@level = current()/@level - 1][1])))/li" />
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>