1

我正在关注本教程:

https://www.w3schools.com/php/php_xml_dom.asp

循环通过 XML 部分是有问题的。PHP 出于某种原因将 DOM 对象视为一个数组。此外, var_dump 除了长度之外没有返回任何关于对象属性的信息,但程序输出看起来像是突然出现的。foreach 可以以某种方式循环对象吗?如果是这样,这些属性包含在哪里(节点名称和节点值),因为 var_dump 没有显示它们?

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

$array_of_nodes=$xml->documentElement->childNodes;

var_dump($array_of_nodes);

foreach($array_of_nodes as $item) {
    echo $item->nodeName."  ".$item->nodeValue."<br>";
}

Var dump 函数返回:

object(DOMNodeList)#3 (1) { ["length"]=> int(9) } #text

但是执行的代码是这样的:

文字=

到 = 托夫

文字=

从 = 贾尼

文字=

标题 = 提醒

文字=

身体 = 这个周末别忘了我!

文字=

4

2 回答 2

1

childNodesDOMNodeList类型的属性。var_dump 没有显示任何内容的原因仅仅是因为 var_dump 仅显示那些由其开发人员通过调用此类 C 函数声明的类属性

ZEND_API int zend_declare_property(...)
ZEND_API int zend_declare_property_null(...)
ZEND_API int zend_declare_property_bool(...)
ZEND_API int zend_declare_property_long(...)
ZEND_API int zend_declare_property_double(...)
ZEND_API int zend_declare_property_string(...)
ZEND_API int zend_declare_property_stringl(...)

资料来源:akond 的回答:为什么 var_dump 不能与 DomDocument 对象一起使用,而 print($dom->saveHTML()) 可以?

也就是说,DOM 扩展的开发者选择不暴露DOMNodeList类的结构。

您可以迭代的原因DOMNodeList是因为它实现Traversable了接口,该接口表明该类可以通过 using 进行迭代foreach

于 2019-02-15T10:58:13.200 回答
0

DOMNodeList实现了几个接口TraversableArrayAccessCountable。这允许使用通用语法访问列表中的节点对象。如果没有它们,您将需要使用如下特定的方法和属性:

for ($i = 0; $c = $nodeList->length; $i < $c; $i++) {
  $node = $nodeList->item($i);
  //...
}

Traversable允许您使用foreach.

foreach ($nodeList as $node) {
  //...
}

ArrayAccess允许您使用数组语法按索引访问节点,它将->item(...)调用替换为[...].

if (isset($nodeList[0])) {
  $node = $nodeList[0];
  //...
}

Countable允许您使用count($nodeList)而不是$nodeList->length.

Traversable最具视觉冲击力。它大大降低了调用的复杂性。但这只是第一个好处。您可以使用 typehints 或instanceof. 这将您的代码解耦,使其更加健壮和可重用。

但是,如果您使用 Xpath 表达式,则通过 DOM 循环会容易得多。如果您之前使用过 CSS 选择器,您可以将 Xpath 表达式视为更强大的兄弟。

$document = new DOMDocument();
$document->load('note.xml');
$xpath = DOMXpath($document);

foreach($xpath->evaluate('/note') as $item) {
    echo 'To: ', $xpath->evaluate('string(to)', $item), "\n";
    echo 'From: ', $xpath->evaluate('string(from)', $item), "\n";
    echo 'Title: ', $xpath->evaluate('string(heading)', $item), "\n";
    echo 'Text: ', $xpath->evaluate('string(body)', $item), "\n";
}
于 2019-02-15T10:18:41.020 回答