2012-09-14 85 views
2

我有一個XML這樣的:隔離特定節點和祖先

<menu> 
    <node id="home" url="url1.php"> 
      <label>Homepage</label> 
      <node id="user" url="url2.php"><label>User profile</label></node> 
      <node id="help" url="url3.php"><label>Help page</label></node> 
    ... 
    </node> 
</menu> 

其用於生成菜單中,XML具有嵌套在下的第一個「家」 node任何級別node標籤。 我通過一個名爲$id的參數與PHP,它給出了當前的活動菜單項。

(該<label>是在一個單獨的標籤而不是屬性,因爲我已經爲許多本地化的標籤,實際的XML就像是<label lang='en'>...</label><label lang='it'>...</label>

的想法是使用不同的XSL來生成主菜單,麪包屑,節標題(頂部菜單)。 對於主菜單我已經成功地做到這一點:

<xsl:template match="menu"> 
    <xsl:apply-templates select="node" /> 
</xsl:template> 

<xsl:template match="//node"> 
    <ul> 
     <li> 
      <a> 
       <xsl:if test="@id=$id"> 
        <xsl:attribute name='class'>active</xsl:attribute> 
       </xsl:if> 
       <xsl:attribute name='href'> 
        <xsl:value-of select="@url" /> 
       </xsl:attribute> 
       <xsl:value-of select="label"/> 
      </a> 
      <xsl:if test="count(child::*)>0"> 
       <xsl:apply-templates select="node" /> 
      </xsl:if> 
     </li> 
    </ul> 
    </xsl:template> 
</xsl:stylesheet> 

和它的作品。但我堅持麪包屑。 如何僅隔離@id=$id及其祖先的特定節點,從家中構建麪包屑至當前頁面?

生成的HTML應該是一個節點廣告第三嵌套層次:

<ul> 
    <li><a href="url1.php">Home</a></li> 
    <li><a href="urla.php">Some child of home</a></li> 
    <li><a href="urlb.php">Some grandchild of home</a></li> 
    <li><a class='active' href="urlc.php">Current page which is child of the above</a></li> 
</url> 
+0

您好!這兩個問題應該是直截了當的,但您可能想要在任何一種情況下顯示您的預期輸出,只是爲了確保。其實,你可能會考慮問問題2作爲一個單獨的問題,以避免問題和答案太大。謝謝! –

+0

@TimC謝謝,我已經在考慮將其他問題分開......我將編輯我的問題:) – Cranio

+0

我認爲X-Path也適用於這樣做嗎?請參閱http://www.w3schools.com/php/func_simplexml_xpath.asp –

回答

1

你可以像這樣,通過選擇活動節點,然後走祖先,像這樣的痕跡:

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

    <xsl:template match="/"> 
     <!--Obviously set your PHP variable here--> 
     <xsl:variable name="id">bananas</xsl:variable> 
     <!--Find this node somewhere in the tree--> 
     <xsl:apply-templates select=".//node[@id=$id]"/> 
    </xsl:template> 

    <xsl:template match="node"> 
     <!--Walk the ancestors--> 
     <xsl:for-each select="ancestor-or-self::node"> 
     <!--Snappy path separator here--> 
      <xsl:text> --> </xsl:text> 
      <a> 
       <xsl:attribute name="href"> 
        <xsl:value-of select="@url" /> 
       </xsl:attribute> 
       <xsl:value-of select="label/text()"/> 
      </a> 
     </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet>  

菜單示例XML:

<menu> 
    <node id="home" url="url1.php"> 
      <label>Homepage</label> 
      <node id="user" url="url2.php"><label>User profile</label></node> 
      <node id="help" url="url3.php"><label>Help page</label></node> 
    </node> 
    <node id="products" url="urlN1.php"> 
     <label>Products</label> 
     <node id="food" url="urlN2.php"> 
      <label>Food</label> 
      <node id="fruit" url="urlN3.php"> 
       <label>Fruit</label> 
       <node id="bananas" url="urlN4.php"> 
        <label>Bananas</label> 
       </node> 
      </node> 
      <node id="clothes" url="urlN3.php"> 
       <label>Clothes</label> 
       <node id="shirts" url="urlN4.php"> 
        <label>Shirts</label> 
       </node> 
      </node> 
     </node> 
    </node> 
</menu> 

編輯更新 - 您更新了Q以顯示麪包屑列表 - 這裏是更新的模板,以防萬一:)

<xsl:template match="node"> 
    <ul> 
     <!--Walk the ancestors--> 
     <xsl:for-each select="ancestor-or-self::node"> 
      <li> 
       <a> 
        <xsl:attribute name="href"> 
         <xsl:value-of select="@url" /> 
        </xsl:attribute> 
        <xsl:value-of select="label/text()"/> 
       </a> 
      </li> 
     </xsl:for-each> 
    </ul> 
</xsl:template> 
+1

隨着一些適應,就像一個魅力。非常感謝你......我的主要問題是理解如何處理模板,其餘的(for-each循環)是非常嚴格的,我只是無法使用它... – Cranio