Pass the node as the second argument to DOMXPath::query
contextnode: The optional contextnode can be specified for doing relative XPath queries. By default, the queries are relative to the root element.
Example:
foreach ($nodes as $node) {
foreach ($x_path->query('h3|a', $node) as $child) {
echo $child->nodeValue, PHP_EOL;
}
}
This uses the UNION operator for a result of
Get me 1
and me too 1
Get me 2
and me too 1
If you don't need any complex querying, you can also do
foreach ($nodes as $node) {
foreach ($node->getElementsByTagName('a') as $a) {
echo $a->nodeValue, PHP_EOL;
}
}
Or even by iterating the child nodes (note that this includes all the text nodes)
foreach ($nodes as $node) {
foreach ($node->childNodes as $child) {
echo $child->nodeName, PHP_EOL;
}
}
However, all of that is unneeded since you can fetch these nodes directly:
$nodes= $x_path->query("/html/body//div[@class='listing']/div[last()]");
foreach ($nodes as $i => $node) {
echo $i, $node->nodeValue, PHP_EOL;
}
will give you two nodes in the last div child of all the divs with a class attribute value of listing and output the combined text node values, including whitespace
0
Get me 1
and me too 1
1
Get me 2
and me too 1
Likewise, the following
"//div[@class='listing']/div[last()]/node()[name() = 'h3' or name() = 'a']"
will give you the four child H3 and A nodes and output
0Get me 1
1and me too 1
2Get me 2
3and me too 1
If you need to differentiate these by name while iterating over them, you can do
foreach ($nodes as $i => $node) {
echo $i, $node->nodeName, $node->nodeValue, PHP_EOL;
}
which will then give
0h3Get me 1
1aand me too 1
2h3Get me 2
3aand me too 1