PHP DOM:相当新手的问题

时间:2008-10-11 00:47:11

标签: php xml dom

我刚刚开始使用PHP修改XML操作,我偶然发现了一些事情。这是我用作测试输入的XML:

<list>
    <activity1> running </activity1>
    <activity2> swimming </activity2>
    <activity3> soccer </activity3>
</list>

现在,我希望这个PHP代码输出'activity1':

$xmldoc = new DOMDocument();
$xmldoc->load('file.xml');

//the line below would make $root the <list> node
$root = $xmldoc->firstChild;

//the line below would make $cnode the first child 
//of the <list> node, which is <activity1>
$cnode = $root->firstChild;

//this should output 'activity1'
echo 'element name: ' . $cnode->nodeName;

相反,此代码输出#text。我可以通过在打印节点名称之前在代码中插入一个新行来解决这个问题:

$cnode = $cnode->nextSibling;

现在,我原本希望打印'activity2',但打印'activity1'。发生了什么事?

4 个答案:

答案 0 :(得分:1)

第一个节点是开始列表标记和activity1标记之间的文本(在本例中为空白),下一个节点是activity1 元素。元素与节点不同。

答案 1 :(得分:1)

要获得预期的行为,您需要传入LIBXML_NOBLANKS作为load()调用的第二个参数

<?php
$xmldoc = new DOMDocument();
$xmldoc->load('file.xml', LIBXML_NOBLANKS);
?>

答案 2 :(得分:1)

如果您使用XPath查询文档,则无需担心此类问题。使用DOMDocument::xpath_eval()评估模式/list/*,无论如何,您将获得的所有元素都是顶级list元素的子元素。

答案 3 :(得分:0)

关于Czimi的答案的说明:删除仅空白节点不会阻止您检查节点的类型(无论是元素,文本节点,注释......)。通常,如果您只对选择元素节点感兴趣,那么您需要执行以下操作:

while($nodeInQuestion->nodeType != 1 && $nodeInQuestion->nextSibling) {
    $nodeInQuestion = $nodeInQuestion->nextSibling;
}

这是一种伪代码。显然,如果你正在寻找一个元素并在找到它之前到达parentNode的childNodes的末尾,你将需要以某种方式处理失败。