I'm trying to parse a remote XML file, which is valid:
$xml = simplexml_load_file('http://feeds.feedburner.com/HammersInTheHeart?format=xml');
The root element is feed
, and I'm trying to grab it via:
$nodes = $xml->xpath('/feed'); //also tried 'feed', without slash
Except it doesn't find any nodes.
print_r($nodes); //empty array
Or any nodes of any kind, so long as I search for them by tag name, in fact:
$nodes = $xml->xpath('//entry');
print_r($nodes); //empty array
It does find nodes, however, if I use wildcards, e.g.
$nodes = $xml->xpath('/*/*[4]');
print_r($nodes); //node found
What's going on?
Unlike DOM, SimpleXML has no concept of a document object, only elements. So if you load an XML you always get the document element.
Output:
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 thefeed
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.Output:
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.
Output:
Xpath expression using with
DOMXpath::evaluate()
can return scalar values.