位置分组:html的xslt转换

时间:2011-08-30 16:44:21

标签: xslt xslt-2.0

我有以下html文件,我想运行转换,以便所有h1,h2,h3标签将转换为相应的div。 h2将永远是h1的嵌套div,如果有2个h2标签,那么它应该有自己的div。同样,h3将始终是h2的嵌套div。

<body>
   <p> this is a text</p>
   <a href="http://yahoo.com">click here</a>
   <h3>this is heading 3</h3>
   <p>text for heading 3</p>
    <h1>
      heading 1
   </h1>
     this is a text for heading 1
     <a href="link"> This is a link </a>
  <h2>
       this is heading 2

  </h2>
          this is a text for heading 2
  <h2>
          this is heading 2 again
  </h2>
         this is a text for heading 2 again
  </body>

” 上面的输出应该是:

<body>
   <p> this is a text</p>
   <a href="http://yahoo.com">click here</a>
   <div>
    <heading>this is heading 3</heading>
   <p>text for heading 3</p>
    <div>

 <div>
  <heading>
    heading 1
  </heading>
  this is a text for heading 1
  <a href="link"> This is a link </a>
  <div>
    <heading>
           this is heading 2
      </heading>
     this is a text for heading 2
 </div>
 <div>
    <heading>
          this is heading 2 again
    </heading>
          this is a text for heading 2 again
  </div>
</div>
</body>

任何帮助将不胜感激。 Currenlty我已经在asp.net中完成了这个,但是想把它转换成xslt。

1 个答案:

答案 0 :(得分:0)

这是一个XSLT 2.0样式表:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="xs mf"
  version="2.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:function name="mf:group" as="node()*">
    <xsl:param name="nodes" as="node()*"/>
    <xsl:param name="level" as="xs:integer"/>
    <xsl:param name="max-level" as="xs:integer"/>
    <xsl:choose>
      <xsl:when test="$level le $max-level">
        <xsl:for-each-group select="$nodes" group-starting-with="*[local-name() eq concat('h', $level)]">
          <xsl:choose>
            <xsl:when test="self::*[local-name() eq concat('h', $level)]">
              <div>
                <xsl:apply-templates select="."/>
                <xsl:sequence select="mf:group(current-group() except ., $level + 1, $max-level)"/>
              </div>
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates select="current-group()"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each-group>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="$nodes"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@*, node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[h1]">
    <xsl:copy>
      <xsl:sequence select="mf:group(node(), 1, 3)"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="h1 | h2 | h3">
    <heading>
      <xsl:apply-templates/>
    </heading>
  </xsl:template>

</xsl:stylesheet>

将Saxon 9.3应用于输入

<body>
 <h1>
    heading 1
 </h1>
     this is a text for heading 1
     <a href="link"> This is a link </a>
  <h2>
       this is heading 2

  </h2>
          this is a text for heading 2
  <h2>
          this is heading 2 again
  </h2>
         this is a text for heading 2 again
</body>

我得到以下输出

<body>
   <div>
      <heading>
    heading 1
 </heading>
     this is a text for heading 1
     <a href="link"> This is a link </a>
      <div>
         <heading>
       this is heading 2

  </heading>
          this is a text for heading 2
  </div>
      <div>
         <heading>
          this is heading 2 again
  </heading>
         this is a text for heading 2 again
</div>
   </div>
</body>

我没有使用任何其他更复杂的输入对XSLT进行测试,因此请自行测试并报告是否遇到任何问题。