2011-08-30 33 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所以測試自己並報告回來,如果你遇到的任何問題。