【问题标题】:Isolate a specific node and ancestors隔离特定节点和祖先
【发布时间】:2012-09-07 08:51:47
【问题描述】:

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

&lt;label&gt; 是在一个单独的标签中,而不是作为属性,因为我有很多本地化标签,实际的 xml 就像&lt;label lang='en'&gt;...&lt;/label&gt;&lt;label lang='it'&gt;...&lt;/label&gt;

这个想法是使用各种 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>

【问题讨论】:

  • 您好!这两个问题都应该是直截了当的,但您可能希望在任何一种情况下都显示您的预期输出,以确保确定。实际上,您可能需要考虑将问题 2 作为一个单独的问题提出,以避免问题和答案太大。谢谢!
  • @TimC 谢谢,我已经在考虑将另一个问题分开......我会编辑我的问题:)
  • 我认为 X-Path 也可以做到这一点?见w3schools.com/php/func_simplexml_xpath.asp
  • @FIG-GHD742:请不要参考 w3schools;请看w3fools.com
  • @FIG-GHD742:我的问题显然与 XSL 相关。

标签: php xml xslt


【解决方案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>

【讨论】:

  • 经过一些调整,就像一个魅力。非常感谢...我的主要问题是了解如何处理模板,其余的(for-each 循环)非常紧张,我就是无法使用它...
猜你喜欢
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-10
  • 2023-03-14
  • 2010-09-17
  • 2015-06-04
相关资源
最近更新 更多