2012-02-04 76 views
7

使用XSLT/XPATH 1.0時,我想要創建HTML,其中class元素的class屬性指示原始XML層次結構中的深度。輸出當前節點在層次結構中的深度

例如,與該XML片段:

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

我想這HTML:

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

不會有多深,這些div元素可以去事先知道的。 div可以是Book - > Chapter。它們可以是卷 - >書 - >章 - >段落 - >線。

我不能依賴@type的值。部分或全部可能是NULL。

回答

16

這有一個非常簡單的和短期的解決方案 - 沒有遞歸,無參數,無xsl:element,沒有xsl:attribute

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

當這個變換所提供的XML文檔施加

<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的回答是好過我一個

<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> 
相關問題