我有包含属性的元素,我需要按顺序重新编号以整理大量已经渗透到XML中的空白。我的来源看起来像:
<ul>
<li book="1" chapter="1" page="1"/>
<li book="1" chapter="6" page="2"/>
<li book="2" chapter="2" page="3"/>
<li book="5" chapter="3" page="1"/>
</ul>
我想创建一个如下所示的列表:
<ul>
<li>1.1.1</li>
<li>1.2.1</li>
<li>2.1.1</li>
<li>3.1.1</li>
</ul>
我基本上按书分组,然后是章节,然后是页面,并重新开始每个级别的计数(例如我的第二行1.6.2是第1册的第二章,但是第二章的第一页所以它变成了1.2.1)。
到目前为止,我已经假设我需要一个for-each-groups:
<xsl:for-each-group select="descendant::li" group-by="concat(@book,'.',@chapter,'.',@page)">
<xsl:sort select="@book" data-type="number" order="ascending"/>
<xsl:sort select="@chapter" data-type="number" order="ascending"/>
<xsl:sort select="@page" data-type="number" order="ascending"/>
<xsl:variable name="a" select="position()"/>
<xsl:for-each-group select="current-group()" group-by="concat(@book,'.',@chapter)">
<xsl:variable name="c" select="position()"/>
<xsl:for-each-group select="current-group()" group-by="@book">
<xsl:variable name="b" select="position()"/>
<!-- Renumbered -->
<li>
<xsl:value-of select="concat($a,'.',$b,'.',$c)"/>
</li>
<!-- Original (for check) -->
<!--<li>
<xsl:value-of select="concat(current-group()[1]/@book,'.',current-group()[1]/@chapter,'.',current-group()[1]/@page)"/>
</li>-->
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:for-each-group>
事情是,我认为我需要在多个级别进行分组(通过@book对@chapter进行重新编号,并通过@ book,@ chapter重新编号@page)以返回正确的位置()在每个组中,据我所知,这是不可能的。我很欣赏我的代码目前还不远,但我不知道下一步该在哪里接受它。
热衷于获得XSLT 2.0解决方案。感谢您的时间 - 非常感谢。
答案 0 :(得分:2)
我认为这比你做的更简单。您不需要concat业务,只需在每个级别按一个属性分组。
<xsl:for-each-group select="li" group-by="@book">
<xsl:variable name="book" select="position()" />
<xsl:for-each-group select="current-group()" group-by="@chapter">
<xsl:variable name="chapter" select="position()" />
<xsl:for-each-group select="current-group()" group-by="@page">
<xsl:variable name="page" select="position()" />
<xsl:for-each select="current-group()">
<li><xsl:value-of select="$book, $chapter, $page" separator="." /></li>
</xsl:for-each>
</xsl:-for-each-group>
</xsl:for-each-group>
</xsl:for-each-group>
如果您需要排序,那么只需在每个级别放置一个<xsl:sort>
。