XSLT 2.0以格式(x.y.z)重新编号分层字符串

时间:2014-07-23 09:58:51

标签: xml xslt

我有包含属性的元素,我需要按顺序重新编号以整理大量已经渗透到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解决方案。感谢您的时间 - 非常感谢。

1 个答案:

答案 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>