1

我刚刚开始用 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

4 回答 4

1

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

于 2008-10-11T01:01:15.067 回答
1

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

<?php
$xmldoc = new DOMDocument();
$xmldoc->load('file.xml', LIBXML_NOBLANKS);
?>
于 2008-10-11T01:40:34.567 回答
1

如果您使用 XPath 来查询您的文档,则无需担心这种奥秘。用于DOMDocument::xpath_eval()评估模式/list/*,无论如何,您将得到的只是顶级元素的子元素list

于 2008-10-11T19:40:28.287 回答
0

A note on Czimi's answer: removing whitespace-only nodes will not prevent you from having to check the type of node (whether it is an element, a text node, a comment...). In general if you're interested in only selecting element nodes, you'll want to do something like this:

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

This is sort of pseudo-code. Obviously you'll need to handle failure somehow if you're looking for an element and reach the end of the parentNode's childNodes before you find it.

于 2008-10-11T06:06:27.307 回答