如何将<h2>和<p>标签包装在xslt中的</p> <section>标签内?

时间:2016-01-20 18:36:34

标签: html xml xslt

我想将标题和段落包含在标记内。当下一个标题出现时,节标记结束。

输入:

<body>
    <h2>text text</h2>
    <p> some text </p>
    <p> some text </p>
    <h2> text text </h2>
    <p> some text </p>
    <p> some text </p>
    <p> some text </p>
</body>

输出:

 <body>
    <section>
        <h2>text text</h2>
        <p> some text </p>
        <p> some text </p>
    </section>
    <section>
        <h2> text text </h2>
        <p> some text </p>
        <p> some text </p>
        <p> some text </p>
    </section>
</body>

1 个答案:

答案 0 :(得分:3)

如评论中所述,这是一个分组问题。

如果您正在使用XSLT 2.0,则可以使用xsl:for-each-group/@group-starting-with ...

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/body">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:for-each-group select="*" group-starting-with="h2">
        <section>
          <xsl:copy-of select="current-group()"/>
        </section>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

如果你坚持使用XSLT 1.0,你可以根据xsl:key的生成ID ... {/ p>使用h2

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="sectElems" match="/body/*[not(self::h2)]" 
    use="generate-id(preceding-sibling::h2[1])"/>

  <xsl:template match="/body">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="h2"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="h2">
    <xsl:variable name="id">
      <xsl:value-of select="generate-id()"/>
    </xsl:variable>
    <section>
      <xsl:copy-of select=".|key('sectElems',$id)"/>
    </section>
  </xsl:template>

</xsl:stylesheet>

这两个样式表都会产生相同的输出。