在XSLT 2中对多个组进行分组

时间:2010-02-01 15:49:28

标签: xslt grouping xslt-2.0 xsl-grouping

我正在尝试将层次结构添加到某些grotty挤压排版XML中。我似乎无法同时管理同一父元素中的几种组。

我拥有(简化,显然):

<article>
  <h1>A section title here</h1>
  <p>A paragraph.</p>
  <p>Another paragraph.</p>
  <bl>Bulleted list item.</bl>
  <bl>Another bulleted list item.</bl>
  <h1>Another section title</h1>
  <p>Yet another paragraph.</p>
</article>

我想要的是什么:

<article>
  <sec>
    <h1>A section title here</h1>
    <p>A paragraph.</p>
    <p>Another paragraph.</p>
    <list>
      <list-item>Bulleted list item.</list-item>
      <list-item>Another bulleted list item.</list-item>
    </list>
  </sec>
  <sec>
    <h1>Another section title</h1>
    <p>Yet another paragraph.</p>
  </sec>
</article>

这几乎适用于列表项目:

<xsl:for-each-group select="*" group-adjacent="boolean(self::BL)">
   <xsl:choose>
      <xsl:when test="current-grouping-key()">
         <list><xsl:apply-templates select="current-group()"/></list>
      </xsl:when>
      <xsl:otherwise>
         <xsl:apply-templates select="current-group()"/>
            </xsl:otherwise>
   </xsl:choose>
 </xsl:for-each-group>

但它只处理文章中的第一个列表;一旦我尝试添加另一个xsl:for-each-group来覆盖这些部分,列表项就会停止工作。

想法?非常感谢提前!

1 个答案:

答案 0 :(得分:2)

下面是一个样本样式表,它为您发布的输入样本生成输出的输出:

<xsl:stylesheet
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:template match="article">
    <xsl:copy>
      <xsl:for-each-group select="*" group-starting-with="h1">
        <sec>
          <xsl:copy-of select="."/>
          <xsl:for-each-group select="current-group() except ." group-adjacent="boolean(self::bl)">
            <xsl:choose>
              <xsl:when test="current-grouping-key()">
                <list>
                  <xsl:apply-templates select="current-group()"/>
                </list>
              </xsl:when>
              <xsl:otherwise>
                <xsl:copy-of select="current-group()"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:for-each-group>
        </sec>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="bl">
    <list-item>
      <xsl:apply-templates/>
    </list-item>
  </xsl:template>

</xsl:stylesheet>