Weird SimpleXML issue - can't reference nodes by name?

北慕城南 提交于 2019-12-02 07:17:28

Unlike DOM, SimpleXML has no concept of a document object, only elements. So if you load an XML you always get the document element.

$feed = simplexml_load_file($xmlFile);
var_dump($feed->getName());

Output:

string(4) "feed"

That means that all Xpath expression have to to be relative to this element or absolute. Simple feed will not work because the context already is the feed element.

But here is another reason. The URL is an Atom feed. So the XML elements in the namespace http://www.w3.org/2005/Atom. SimpleXMLs magic syntax recognizes a default namespace for some calls - but Xpath does not. Here is not default namespace in Xpath. You will have to register them with a prefix and use that prefix in your Xpath expressions.

$feed = simplexml_load_file($xmlFile);
$feed->registerXpathNamespace('a', 'http://www.w3.org/2005/Atom');
foreach ($feed->xpath('/a:feed/a:entry[position() < 3]') as $entry) {
  var_dump((string)$entry->title);
}

Output:

string(24) "Sharing the goals around"
string(34) "Kouyate inspires Hammers' comeback"

However in SimpleXML the registration has to be done for each object you call the xpath() method on.

Using Xpath with DOM is slightly different but a lot more powerful.

$document = new DOMDocument();
$document->load($xmlFile);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('a', 'http://www.w3.org/2005/Atom');

foreach ($xpath->evaluate('/a:feed/a:entry[position() < 3]') as $entry) {
  var_dump($xpath->evaluate('string(a:title)', $entry));
}

Output:

string(24) "Sharing the goals around"
string(34) "Kouyate inspires Hammers' comeback"

Xpath expression using with DOMXpath::evaluate() can return scalar values.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!