在XSLT 2中使用与组相邻的for-each-group进行分组和包装

时间:2018-08-15 13:40:46

标签: xml xslt grouping wrapping

很明显,我对XSLT 2中的分组工作方式的了解还不够。我确定以xsl:for-each-group为属性的group-adjacent方法是正确的。但是,我没有得到想要的结果。

我想对XML源中的几个相邻元素进行分组。通过后代元素的属性值来标识元素。我需要用一个新元素(例如p div="lernz")包装它们。有时这些元素显示为邻居,有时却不显示。

我的样式表没有得到正确的结果。有时,我认为应该是一组的第一项之前的元素会匹配。但是到目前为止,在我的研究结果中,我认为属于一个组的每个项目都被包装了。错误在哪里?任何帮助将不胜感激。

XML输入

 <wx:sect>
  <w:p>
    <w:pPr w:val = 'Lern'/>
  </w:p>
  <w:p>
    <w:pPr w:val = 'Lern'/>
  </w:p>
  <w:p>
    <w:pPr w:val = 'Merk'/>
  </w:p>
  <w:p>
    <w:pPr w:val = 'Lern'/>
  </w:p>
  <w:p>
    <w:pPr w:val = 'Merk'/>
  </w:p>
</w:sect>

所需的输出

<wx:sect>
   <p div="wrapper-lernz">
       <w:p>
          <w:pPr w:val = 'Lern'/>
        </w:p>
        <w:p>
          <w:pPr w:val = 'Lern'/>
        </w:p>
    </p>
        <w:p>
          <w:pPr w:val = 'Merk'/>
        </w:p>
    <p div="wrapper-lernz">
      <w:p>
        <w:pPr w:val = 'Lern'/>
      </w:p>
    </p>
      <w:p>
        <w:pPr w:val = 'Merk'/>
      </w:p>
</w:sect>

我的样式表(部分)

<xsl:template match="//w:p[w:pPr[@w:val]]">
    <xsl:for-each-group select="current()" group-adjacent="//@w:val = 'Lern">
         <p div="wrapper-lernz">
             <xsl:value-of select="current-group()"/>
          </p>
        </xsl:for-each-group>
    </xsl:template>

1 个答案:

答案 0 :(得分:3)

您的模板匹配w:p,但是如果要对相邻元素进行分组,则应该匹配父w:sect标签。通过执行xsl:for-each-group select="current()",您正在尝试对单个元素进行分组。

要只处理将“ lern”元素放入容器标记中,应在“ w:val”值上使用group-adjacent =,然后使用xsl:choose来决定是否添加父标记

尝试此模板:

<xsl:template match="//w:sect[w:p[w:pPr/@w:val]]">
  <xsl:copy>
    <xsl:for-each-group select="w:p" group-adjacent="w:pPr/@w:val">
      <xsl:choose>
        <xsl:when test="current-grouping-key() = 'Lern'">
          <p div="wrapper-lernz">
             <xsl:copy-of select="current-group()"/>
          </p>
        </xsl:when>
        <xsl:otherwise>
          <xsl:copy-of select="current-group()"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

(请注意,它也执行xsl:copy-of而不是xsl:value-of,因为xsl:value-of仅返回节点的文本值,而不是节点本身)