2013-04-11 51 views
0

我想表示一個像目錄樹一樣的XML結構。它是一個導航編輯器,因此元素名稱鏈接(組)和鏈接(組中的項目)。所以我有不同的圖像:i節點,l節點,t節點和e節點圖像(其中e是空的,其他是虛線)。 HTML應該是一個標準表格。每個鏈接都在其新的tr中。XML結構樹呈現 - 如何測試遞歸內的父母/兄弟姐妹?

到目前爲止,一切都很好...

so far so good

但是:

here's the dealio

在第一種情況下按預期的圖像,但在第二個你看到我被卡住了:只要有一個L節點(該級別上的最後一個元素),所有後續鏈接都應該顯示該級別的空節點圖像 - 但現在有一個I節點。 所以我需要一些關於如何實現這一點的建議。我需要檢查它的前面的兄弟姐妹的XML嗎?或者我可以通過傳遞另一個參數來遞歸調用?任何幫助表示讚賞...我寧願做正確比開始修復了JS的HTML;)

的XML:

<navigation> 
    <links> 
    <link> 
     <text>Google</text> 
     <links> 
     <link> 
      <text>Yahoo</text> 
     </link> 
     <link> 
      <text>Amazon</text> 
     </link> 
     </links> 
    </link> 
    <link /> 
    <link /> 
    <link /> 
    ... 
    </links> 
</navigation> 

的XSL:

<xsl:template match="navigation"> 
<table> 
    <xsl:for-each select="links"> 
     <xsl:apply-templates select="."> 
      <xsl:with-param name="level" select="'1'" /> 
      <xsl:with-param name="children" select="count(*[links/link])" /> 
     </xsl:apply-templates> 
    </xsl:for-each> 
</table> 
</xsl:template> 

<xsl:template match="links"> 
    <xsl:param name="level" /> 
    <xsl:param name="children" /> 
    <xsl:variable name="count" select="count(link)" /> 
    <xsl:for-each select="link"> 
     <tr> 
      <xsl:attribute name="class">level<xsl:value-of select="$level" /></xsl:attribute> 
      <td> 
       <xsl:call-template name="nodeimage.loop"> 
        <xsl:with-param name="level" select="$level"></xsl:with-param> 
        <xsl:with-param name="position" select="position()"></xsl:with-param> 
        <xsl:with-param name="count" select="$count" /> 
       </xsl:call-template> 
       <strong><xsl:value-of select="text" /></strong> 
      </td> 
     </tr> 
     <!-- if a link has children... --> 
     <xsl:if test="*[link]"> 
      <xsl:apply-templates select="links"> 
       <xsl:with-param name="level" select="$level + 1"/> 
       <xsl:with-param name="children" select="count(*[link])"/> 
      </xsl:apply-templates> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

<xsl:template name="nodeimage.loop"> 
    <xsl:param name="level"/> 
    <xsl:param name="position"/> 
    <xsl:param name="count"/> 

    <!-- debug this 
    <xsl:value-of select="$position" />of<xsl:value-of select="$count" />, level<xsl:value-of select="$level" /> 
    --> 
    <xsl:if test="$level = 1"> 
     <xsl:choose> 
      <xsl:when test="$position = $count"><!-- last one on same level --> 
       <img class="textmiddle" src="/images/backend/l-node.png" /> 
      </xsl:when> 
      <xsl:otherwise> 
       <img class="textmiddle" src="/images/backend/t-node.png" /> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:if> 
    <xsl:if test="$level &gt; 1"> 
     <img class="textmiddle" src="/images/backend/i-node.png" /> 
    </xsl:if> 
    <xsl:if test="$level &gt; 1"> 
     <xsl:call-template name="nodeimage.loop"> 
      <xsl:with-param name="level"> 
       <xsl:value-of select="$level - 1"/> 
      </xsl:with-param> 
      <xsl:with-param name="position"> 
       <xsl:value-of select="$position"/> 
      </xsl:with-param> 
      <xsl:with-param name="count"> 
       <xsl:value-of select="$count"/> 
      </xsl:with-param> 
     </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

回答

1

這些模板(爲XSLT 1.0編寫)應該能夠呈現您的樹結構 - 它們不使用遞歸,而是使用匹配模板來處理一般結構,然後使用模板化模板來處理圖像(通過處理上下文節點的每個祖先):

<xsl:template match="navigation"> 
    <table> 
     <thead> 
      <xsl:call-template name="headers" /> 
     </thead> 
     <tbody> 
      <xsl:apply-templates select="links" /> 
     </tbody> 
    </table> 
</xsl:template> 

<xsl:template match="link"> 
    <xsl:variable name="chain" select="ancestor-or-self::link" /> 
    <tr class="level{count($chain)}"> 
     <td> 
      <xsl:apply-templates select="$chain" mode="tracks"> 
       <xsl:with-param name="context" select="." /> 
      </xsl:apply-templates> 
      <strong><xsl:value-of select="text" /></strong> 
     </td> 
     <td><button>Append new link</button></td> 
     <td><xsl:value-of select="url" /></td> 
    </tr> 
    <xsl:apply-templates select="links" /> 
</xsl:template> 

<xsl:template match="link" mode="tracks"> 
    <xsl:param name="context" /> 
    <xsl:variable name="isSame" select="generate-id(.) = generate-id($context)" /> 
    <xsl:variable name="pos" select="count(preceding-sibling::link)" /> 
    <xsl:variable name="isLast" select="not(following-sibling::link)" /> 
    <xsl:variable name="type"> 
     <xsl:choose> 
     <xsl:when test="$isSame"> 
      <xsl:if test="(following::link or links/link) and not($isLast)">t</xsl:if> 
      <xsl:if test="$isLast">l</xsl:if> 
     </xsl:when> 
     <xsl:when test="$isLast and links/link">e</xsl:when> 
     <xsl:when test="following::link and links/link">i</xsl:when> 
     <xsl:when test="not(following::link)">e</xsl:when> 
    </xsl:choose> 
    </xsl:variable> 
    <xsl:call-template name="node-type"> 
     <xsl:with-param name="type" select="$type" /> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="node-type"> 
    <xsl:param name="type" select="'t'" /> 
    <img class="textmiddle" src="/images/backend/{$type}-node.png" /> 
</xsl:template> 

<xsl:template name="headers"> 
    <tr> 
     <th>Link</th> 
     <th>&#160;</th> 
     <th>URL</th> 
    </tr> 
</xsl:template> 

(請注意,應用模板到links節點將使用內置模板隨後處理link節點,如果沒有匹配模板links

+0

更新並獲得成功。 :)開心快樂的喜悅 – iroybot 2013-04-28 21:52:17