2011-08-30 5 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 2.0 솔루션보다 훨씬 짧음) 효율적인 키를 사용하는 완전한 XSLT 1.0 솔루션에 대한 내 대답을보십시오. –

답변

0
색슨 9.3인가하면

<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> 

:

여기 2.0 XSLT 스타일 시트 인 입력

<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> 

에 내가 그렇게 자신을 테스트하고 문제가 발생하면 다시보고 다른 더 복잡한 입력과 XSLT를 테스트하지 않은 다음과 같은 출력을

<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> 

를 얻을.