XPath in PHP: Problems Solved

Album Cover: Black Holes and Revelations

"Come ride with me through the veins of history. I'll show you a god who falls asleep on the job."
Muse / Knights of Cydonia

Posted on April 24, 2004 1:28 AM in XML
Warning: This blog entry was written two or more years ago. Therefore, it may contain broken links, out-dated or misleading content, or information that is just plain wrong. Please read on with caution.

In my last post I was scrambling to find any semblance of functionality in PHP 5's XPath handling. It seems that because PHP 5 is only in a release candidate state, there aren't very many people who have gotten their hands dirty with the code...especially the XPath code.

Right now, a Google search on the subject returns the usual suspects like Zend and PHPBuilder, but not a whole lot in terms of developer discussion on common practices and techniques. Unfortunately, one of the items in the search results is a presentation slide offering the following code sample:

$xp = new domxpath($dom);
$result = $xp->query("/html/head/title");
print $result[0]->firstChild->data;

It would be nice if these people would actually try their source code before they add it to their presentation. Because the DomXPath class's query() function returns a domNodeList, you can't access the $result variable as an array.

There is some good news to share, though. Most of the problems I mentioned in my last post have been eradicated. It turns out, for some reason or another, PHP 5 doesn't seem to like the format of my Atom XML feed, even though it is a perfectly valid XML feed. All it took was testing against the following XML file to start seeing some of the XPath query results that I was expecting:

<?xml version="1.0"?>
<bernie>
 <likes id="1">Porsche</likes>
 <likes id="2">Ferrari</likes>
 <likes id="3">Mercedes Benz</likes>
 <dislikes id="1">Honda</dislikes>
 <dislikes id="2">Ford</dislikes>
</bernie>

With that XML file, which we'll refer to as bernie.xml, I was able to use the following PHP code...

<?
$dom = new DomDocument();
$dom->load("bernie.xml");
$xp = new domxpath($dom);

$results = $xp->query("/bernie/likes");
foreach ($results as $node)
 print($node->textContent."<br />");

$results = $xp->query("//dislikes/..");
foreach ($results as $node)
 print($node->textContent."<br />");
?>

...to generate the following results:

Porsche
Ferrari
Mercedes Benz
Porsche Ferrari Mercedes Benz Honda Ford

The first three lines were generated by the first query, grabbing the textContent of each of the likes nodes and printing them out one-per-line. The last line was generated by the second query, first by finding the parents of every dislikes node in the XML document (in our case there is only one parent found, the bernie node) and then printing the textContent contained within that single node.

Comments

Stephen Beattie on May 16, 2007 at 5:33 AM:

I know this is now and old post but I thought I'd add my comments for anyone else ending up on this page trying to fathom DOMXPath on PHP5 out. Bernie', you're right on the documentation being somewhat light at php.net.

I had a similar problem to Bernie and found that I was creating my xpath object before I'd loaded my DOMDocument with any kind of data. Subsequently any queries using the xpath object were failing. Always remember to load some XML or create a root-level element before initialising your xpath object. As soon as I did this I was up and rolling again.

Thanks for providing your working code Bernie that allowed me to spot this gotcha in mine.

Permalink

affordable logo design service on September 30, 2016 at 5:16 AM:

It was wondering if I could use this write-up on my other website, I will link it back to your website though.Great Thanks.

Permalink

how do i shut down computer in windows 10 on January 31, 2018 at 12:24 AM:

Well you can and you will know shut down and restart short cut commands .

Permalink

Post Comments

If you feel like commenting on the above item, use the form below. Your email address will be used for personal contact reasons only, and will not be shown on this website.

Name:

Email Address:

Website:

Comments:

Check this box if you hate spam.