关于xslt:如何选择一个节点及其兄弟节点,直到出现同一节点为止

How to select a node and its siblings until the same node from the start occurs

这可能是一个棘手的问题。

我有此文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<html>
   title1
   <p>content</p>
   
<ul>

     
<li>
item
</li>

   
</ul>

   title2
   <p>content</p>
   <p>another content</p>
   title3
   
     
<li>
<p>text</p>
</li>

   
</html>

此示例显示我有一些html,其中" sections"由标题分开。它是标题,然后是元素的各种混合,然后又是标题。

我希望使用XSLT 2将这些部分package为div

因此,我想使用标题来选择组。基本上,分组规则是:

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

对"和"的强调非常重要,因为我想出了XPath公式,该公式仅在h1个节点之间选择节点,或者从第一个到最后一个h1节点之间进行选择,而忽略它们之间的h1。我也需要获得该标题。我认为使用XPath很难实现这一点,但是我无法使其正常工作。

为获得最佳理解,它应该是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<html>
   
      title1
      <p>content</p>
     
<ul>

         
<li>
item
</li>

     
</ul>

   
   
      title2
      <p>content</p>
      <p>another content</p>
   
   
      title3
     
         
<li>
<p>text</p>
</li>

     
   
</html>

您可以为此使用group-starting-with

1
2
3
4
5
6
7
8
9
10
11
12
13
<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">
       
          <xsl:copy-of select="current-group()" />
       
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<html>
   
      title1
      <p>content</p>
     
<ul>

         
<li>
item
</li>

     
</ul>

   
   
      title2
      <p>content</p>
      <p>another content</p>
   
   
      title3
     
         
<li>

            <p>text</p>
         
</li>

     
   
</html>

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

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

这将产生相同的结果。