2012-09-14 69 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