如何选择节点及其兄弟节点,直到从一开始就出现相同的节点

时间:2014-11-04 15:53:25

标签: xslt xpath xslt-2.0 xpath-2.0 xslt-grouping

这可能是个棘手的问题。

我有这个文件:

<html>
   <h1>title1</h1>
   <p>content</p>
   <ul>
      <li>item</li>
   </ul>
   <h1>title2</h1>
   <p>content</p>
   <p>another content</p>
   <h1>title3</h1>
   <ol>
      <li><p>text</p></li>
   </ol>
</html>

这个例子表明我有一些html,其中&#34;部分&#34;按标题划分。这是标题,然后是各种元素的混合,然后再重新标题。

我希望使用XSLT 2将这些部分用div包装。

所以,我想使用<h1>标题来选择群组。基本上,分组规则是:

  • 选择h1 所有兄弟姐妹,直到另一个h1出现。

&#34;和#34; 的这种压力非常重要,因为我提出了XPath公式,它只在h1节点之间选择节点或从第一个到最后一个节点选择h1忽略它们之间的h1。我也需要得到这个标题。我不认为使用XPath很难实现这一点,但我无法使其工作。

为了最好的理解,这里应该是这样的:

<html>
   <div>
      <h1>title1</h1>
      <p>content</p>
      <ul>
         <li>item</li>
      </ul>
   </div>
   <div>
      <h1>title2</h1>
      <p>content</p>
      <p>another content</p>
   </div>
   <div>
      <h1>title3</h1>
      <ol>
         <li><p>text</p></li>
      </ol>
   </div>
</html>

1 个答案:

答案 0 :(得分:2)

您可以使用group-starting-with

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="html">
    <xsl:copy>
      <xsl:for-each-group select="node()" group-starting-with="h1">
        <div>
          <xsl:copy-of select="current-group()" />
        </div>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

在样本上运行时,结果为:

<html>
   <div>
      <h1>title1</h1>
      <p>content</p>
      <ul>
         <li>item</li>
      </ul>
   </div>
   <div>
      <h1>title2</h1>
      <p>content</p>
      <p>another content</p>
   </div>
   <div>
      <h1>title3</h1>
      <ol>
         <li>
            <p>text</p>
         </li>
      </ol>
   </div>
</html>

作为一些额外的信息,如果您想使用group-by来执行此操作,您可以这样做:

  <xsl:for-each-group select="node()" group-by="self::h1 | preceding-sibling::h1[1]">

这应该产生相同的结果。