使用PHP解析XML导航站点地图

时间:2011-02-18 16:10:31

标签: php xml sitemap

我正在从XML文件实现PHP站点地图解析器。我的表现相对较好。但是,我需要解析器更具动态性。我需要实现一个递归函数,它将为找到的每个child_node继续循环。节点可以在另一个child_node中包含许多child_nodes。我到目前为止所做的是为每个child_node实现一个带有不同变量名的单独foreach循环,但这是不可接受的,因为它不是那么灵活。

这是我的xml文件:

<sitemap>
    <node>
        <id>rootnode</id>
        <link>home.html</link>
    </node>
    <node>
        <id>about</id>
        <link>about.html</link>
    </node>
    <node>
        <id>contact</id>
        <link>contact.html</link>
        <child_node>
            <id>contact_uk</id>
            <link>contact_uk.html</link>
            <child_node>
                <id>customer_support_uk</id>
                <link>customer_support_uk.html</link>
            </child_node>
        </child_node>
        <child_node>
            <id>contact_usa</id>
            <link>contact_usa.html</link>
        </child_node>
    </node>

    <node>
        <id>products</id>
        <link>products.html</link>
    </node>
</sitemap>

您可以注意到节点联系人在child_node中有一个child_node。这是我需要递归函数的地方。

这是我目前的PHP代码:

    $source = 'sitemap.xml';


    // load as file
    $sitemap = simplexml_load_file($source, null, true);


    foreach ($sitemap->node as $node) {

        if ($node->child_node != "") {
            echo "$node->link<br/>";
            foreach ($node->child_node as $child) {
                if ($child->child_node != "") {
                    echo "&nbsp;&nbsp;" . $child->link . "<br/>";
                    foreach ($child->child_node as $innerchild) {
                        echo "&nbsp;&nbsp;&nbsp;&nbsp;" . $innerchild->link . "<br/>";
                    }
                } else {
                    echo "&nbsp;&nbsp;" . $child->link . "<br/>";
                }
            }
        } else {
            echo "$node->link<br/>";
        }
    }

这个PHP有正确的输出,但我必须为其父child_node中的每个child_node创建另一个单独的foreach循环。有人能指出我如何改变我的PHP代码以便遍历站点地图中找到的child_node中的每个child_node吗?

非常感谢!

2 个答案:

答案 0 :(得分:5)

未经测试......但应该有效:

function print_node($node, $level){
 echo str_repeat("-",$level);
 echo "$node->link\n";
 if ($node->child_node != "") {
       foreach ($node->child_node as $child) {
          print_node($child,$level+1);
       }
  }

}
$source = 'sitemap.xml';


$sitemap = simplexml_load_file($source, null, true);
foreach ($sitemap->node as $node)
    print_node($node,0);

答案 1 :(得分:1)

您需要一个递归函数,并在处理每个顶级节点时调用它。

function processChildren( $node )
{
    foreach( $node->child_node as $child )
    {
        echo "$child->link<br/>";
        if( count( $child->child_node ) )
        {
            processChildren( $child );
        }
    }
}

我将作为一个有趣的练习留给读者如何让缩进工作。 ; - )