2012-02-04 12 views
7

XSLT/XPATH 1.0を使用して、span要素のclass属性が元のXML階層の深さを示すHTMLを作成したいとします。例えば階層内の現在のノードの深さを出力

、このXMLフラグメントで:事前に知られていないどのように深いこれらdiv要素が行くことができる

<span class="level1">Book 3</span> 
<span class="level2">Chapter 6</span> 
<span class="level3">Verse 12</span> 

<text> 
    <div type="Book" n="3"> 
     <div type="Chapter" n="6"> 
      <div type="Verse" n="12"> 
      </div> 
     </div> 
    </div> 
</text> 

私はこのHTMLをしたいです。 divは、書籍 - >章とすることができます。 Volume - > Book - > Chapter - > Paragraph - > Lineなどがあります。

@typeの値に依存することはできません。いくつかまたはすべてがNULLである可能性があります。

答えて

16

よりも優れている - 何の再帰、パラメータなし、ノーxsl:element、無xsl:attributeを:この変換は、提供されるXML文書に適用され

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

<xsl:template match="div"> 
    <span class="level{count(ancestor::*)}"> 
    <xsl:value-of select="concat(@type, ' ', @n)"/> 
    </span> 
    <xsl:apply-templates/> 
</xsl:template> 
</xsl:stylesheet> 

:指名手配、正しい結果がを生産している

<text> 
    <div type="Book" n="3"> 
     <div type="Chapter" n="6"> 
      <div type="Verse" n="12"></div></div></div> 
</text> 

<span class="level1">Book 3</span> 
<span class="level2">Chapter 6</span> 
<span class="level3">Verse 12</span> 

説明:テンプレート、AVTとcount()機能を適切に使用します。

0

通常、XSLでは再帰を使用します。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" indent="yes"/> 

    <xsl:template match="/text"> 
    <html> 
     <xsl:apply-templates> 
     <xsl:with-param name="level" select="1"/> 
     </xsl:apply-templates> 
    </html> 
    </xsl:template> 


    <xsl:template match="div"> 
    <xsl:param name="level"/> 

    <span class="{concat('level',$level)}"><xsl:value-of select="@type"/> <xsl:value-of select="@n"/></span> 

    <xsl:apply-templates> 
     <xsl:with-param name="level" select="$level+1"/> 
    </xsl:apply-templates> 
    </xsl:template> 


</xsl:stylesheet> 
5

または再帰を使用しない - しかし、Dimitreの答えは、これは非常にシンプルで短いソリューションを持っていない私の1

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 

<xsl:template match="/text"> 
    <html> 
     <body> 
      <xsl:apply-templates/> 
     </body> 
    </html> 
</xsl:template> 

<xsl:template match="//div"> 
    <xsl:variable name="depth" select="count(ancestor::*)"/> 
    <xsl:if test="$depth > 0"> 
     <xsl:element name="span"> 
      <xsl:attribute name="class"> 
       <xsl:value-of select="concat('level',$depth)"/> 
      </xsl:attribute> 
      <xsl:value-of select="concat(@type, ' ' , @n)"/> 
     </xsl:element> 
    </xsl:if> 
    <xsl:apply-templates/> 
</xsl:template> 

</xsl:stylesheet>