找出XML节点是否有子节点

时间:2011-07-19 08:29:58

标签: php xml

我目前正在编写一个处理XML文档的PHP类。具体地说,这种类的某种方法需要知道节点是否有子节点或者它是否是“叶子”。假设XML结构如下:

<root>
    <obj1>
         <obj2>red</obj1>
         <obj3>green</obj3>
         <obj4>
             <obj5></obj5>
         </obj4>
    </obj1>
</root>

我认为root,obj1和obj4是节点,而obj2,obj3和obj5是叶子,本身没有子节点。

我使用的代码如下:

$MyDoc = NewDOMDocument();
$node = $MyDoc->getElementsByTagName($node_name);
foreach($node as $node) {
    if($node->hasChildNodes()) {
        return true;
    }
    return false;
}

但是,对于我应用它的任何对象,这样的代码返回“true”,无论它是否有childNodes。

我做错了什么?

2 个答案:

答案 0 :(得分:2)

$node = $MyDoc->getElementsByTagName($node_name);
foreach($node as $node)

你正在覆盖你的变量。尝试:

$nodelist = $MyDoc->getElementsByTagName($node_name);
foreach($nodelist as $node)

答案 1 :(得分:1)

  

我认为root,obj1和obj4是节点,而obj2,obj3和obj5是叶子,本身没有子节点。

你错了。 DOM树是节点的层次结构。这意味着DOMText,DOMElements,DOMDocument等都继承自DOMNode。请再次浏览DOMDocument in php以了解该概念。

以下是文档的树层次结构:

root
    #text
    obj1
        #text
        obj2
            #text
        #text
        obj3
            #text
        #text
        obj4
            #text
            obj5
            #text
        #text
    #text

在你提到的那些中,只有obj5是一片叶子。因此:

var_dump($dom->getElementsByTagName('obj5')->item(0)->hasChildNodes()); // false

您不能仅使用任何DOMNode方法计算DOMElement节点(除非您想迭代每个子节点并检查其nodeType)。但是你可以使用XPath:

$dom = new DOMDocument;
$dom->loadXML($xml);
$xp = new DOMXPath($dom);
var_dump( $xp->evaluate('count(/root/obj1/obj2/*)') ); // 0

*只考虑DOMElements(使用考虑所有节点的node())。