2011-08-30 35 views
2

我有下面的html文件,我想运行一个转换,这样所有的h1,h2,h3标签都会转换成相应的div。 h2将永远是h1的嵌套div,如果有2个h2标签,那么它应该有自己的div。同样的方式h3将永远是h2的嵌套div。位置分组:html的xslt转换

<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

+0

我认为你的源代码需要一个根元素,所以如果你的HTML看起来和你发布的完全一样,那么它就无法工作。 – DanMan

+0

嗨DanMan,我已经添加了根元素体。 – atif

+0

好问题,+1。请参阅我的答案,以获取完整的XSLT 1.0解决方案,该解决方案非常简单,非常简短(比所提供的XSLT 2.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> 

当与撒克逊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所以测试自己并报告回来,如果你遇到的任何问题。