Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Traversing child nodes with PHP DOMXpath?

I'm having some trouble understanding what exactly is stored in childNodes. Ideally I'd like to do another xquery on each of the child nodes, but can't seem to get it straight. Here's my scenario: Data:

<div class="something">
    <h3>
        <a href="link1.html">Link text 1</a>
    </h3>
    <div class"somethingelse">Something else text 1</div>
</div>
<div class="something">
    <h3>
        <a href="link2.html">Link text 2</a>
    </h3>
    <div class"somethingelse">Something else text 2</div>
</div>
<div class="something">
    <h3>
        <a href="link3.html">Link text 3</a>
    </h3>
    <div class"somethingelse">Something else text 3</div>
</div>

And the code:

$html = new DOMDocument();
$html->loadHtmlFile($local_file);
$xpath = new DOMXPath( $html );
$nodelist = $xpath->query( "//div[@class='something']");
foreach ($nodelist as $n) {
    Can I run another query here? }

For each element of "something" (i.e., $n) I want to access the values of the two pieces of text and the href. I tried using childNode and another xquery but couldn't get anything to work. Any help would be greatly appreciated!

like image 205
Bryan Avatar asked Oct 25 '11 23:10

Bryan


2 Answers

Yes you can run another xpath query, something like that :

foreach ($nodelist as $n)
{
    $other_nodes = $xpath->query('div[@class="somethingelse"]', $n);

    echo $other_nodes->length;
}

This will get you the inner div with the class somethingelse, the second argument of the $xpath->query method tells to query to take this node as context, see more http://fr2.php.net/manual/en/domxpath.query.php

like image 161
mravey Avatar answered Sep 22 '22 18:09

mravey


If I understand your question correctly, it worked when I used the descendant:: expression. Try this:

foreach ($nodelist as $n) {
    $other_nodes = $xpath->query('descendant::div[@class="some-descendant"]', $n);

    echo $other_nodes->length;
    echo $other_nodes->item(0)->nodeValue;
}

Although sometimes it's just enough to combine queries using the // path expression for narrowing your search. The // path expression selects nodes in the document starting from the current node that match the selector.

$nodes = $xpath->query('//div[@class="some-descendant"]//div[@class="some-descendant-of-that-descendant"]');

Then loop through those for the stuff you need. Hope this helps.

like image 29
Will Schoenberger Avatar answered Sep 21 '22 18:09

Will Schoenberger