XSLT - 分析给定节点的兄弟节点

时间:2015-09-09 17:33:44

标签: xml xslt xslt-2.0

我有一个xml如下,

    <doc>
    <h1>header 1</h1>
    <p>para</p>
    <p>para</p>

    <h1>header 2</h1>
    <p>para</p>
    <h2>header 2 sub h1</h2>
    <h2>header 2 sub h2</h2>

    <h1>header 3</h1>
    <p>para</p>
    <p>para</p>

    <h1>header 4</h1>
    <h2>header 4 sub h1</h2>
    <p>para</p> 

</doc>

我需要的是按顺序获取所有<h1><h2>个节点,并创建一个无序列表,

所以最终输出应该是这样的,

    <doc>
        <ul>
            <li><h1>header 1</h1><li>

            <li><h1>header 2</h1></li>
            <ul> 
              <li><h2>header 2 sub h1</h2></li>
              <li><h2>header 2 sub h2</h2><li>
            </ul>

            <li><h1>header 3</h1></li>

            <li><h1>header 4 sub h1</h1></li>
            <ul>
              <li><h2>zz</h2></li>
            </ul>
       </ul>
  </doc>

我写的xsl如下,

<xsl:template match="doc">
        <doc>
            <xsl:for-each select="//h1">
                <li>
                    <xsl:apply-templates/>
                </li>
                <ul>
                    <xsl:for-each-group select="//h2" group-by="count(preceding::h1)">
                        <li><xsl:apply-templates/></li>
                    </xsl:for-each-group>
                </ul>
            </xsl:for-each>
        </doc>
    </xsl:template>

结果如下:

<doc>
    <li>header 1</li>
    <ul><li>header 2 sub h1header 4 sub h1</li></ul>
    <li>header 2</li>
    <ul></li>header 2 sub h1header 4 sub h1</li></ul>
    <li>header 3</li>
    <ul></li>header 2 sub h1header 4 sub h1</li></ul>
    <li>header 4</li>
    <ul></li>header 2 sub h1header 4 sub h1</li></ul>
</doc>

正如您所看到的,我已经使用了每个groping来在相关的<h2>节点下添加<h1>个节点。 (这是我可以想到的在其相关<h2>节点下添加<h1>个节点的解决方案。)但是你可以看到它没有给出预期的输出。

你能建议一种方法如何改变我的代码以获得预期的结果。或者可能是获得预期结果的另一种方法?

1 个答案:

答案 0 :(得分:1)

你想要以小组为起点。

<xsl:template match="doc">
  <ul>
    <xsl:for-each-group select="*" group-starting-with="h1">
      <li><xsl:copy-of select="."/></li>
      <ul>
       <xsl:apply-templates select="current-group()[self::h2]"/>
      </ul>
    </xsl:for-each-group>
  </ul>
</xsl:template>

你真的想要这个输出吗?在HTML中,<ul>元素的所有子元素都必须是<li>个元素。但是,就XSLT而言,您应该能够采用这种方法。