隔离特定节点和祖先

时间:2012-09-14 07:56:12

标签: php xml xslt

我有一个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在第一个“home”node下的任何级别嵌套node个标记。 我用PHP传递一个名为$id的参数,它给出了当前活动的菜单项。

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

1 个答案:

答案 0 :(得分: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>
相关问题