PHP xpath issues ->item(0)->nodeValue

2.1k views Asked by At

Based on the following XML I want to retrieve the product name and image of a certain node (ID)

<?xml version="1.0" encoding="utf-8"?>
<clients>
    <client id="A">
        <product>Name of product A</product>
        <image>Product image name A</image>
    </client>
    <client id="B">
        <product>Name of product B</product>
        <image>Product image name B</image>
    </client>
</clients>

This is the PHP Code:

$doc      = DOMDocument::load('clients.xml');
$xpath    = new DOMXPath($doc);
$query    = '//client[@id="A"]'; 
$info = $xpath->query($query);

If I do $info->item(0)->nodeValue I get both information together and not individually:

Name of product A
Product image name A

But I want to get ->product->nodeValue and image->nodeValue based on the client ID. How can I do that? Doing $info->item(0)->product->nodeValue for example doesn't work.

->item(0)->nodeValue gives everything inside that particular item (in this case 0)

2

There are 2 answers

0
ThW On

You use XPath to fetch the nodes. The result of an XPath location path is a list of node. ->item(0) returns the first node in this list.This is the client element node.

Calling DOMElement:$nodeValue always returns all descendent text nodes as a string. In you case the text nodes inside the product and the image element nodes.

You will have the to fetch the child nodes if you want the values separately.

$dom = new DOMDocument();
$dom->loadXML($xml);
$xpath = new DOMXpath($dom);

foreach ($xpath->evaluate('//client[@id="A"]/*[self::product or self::image]') as $child) {
    echo $child->localName, ': ', $child->nodeValue, "\n";
}

Output:

product: Name of product A
image: Product image name A
0
Mike On

Your result returns a single node (client). The nodevalue of that node is all of the text underneath it.

Try: "//client [@id='A']/*[name()='product' or name()='image']" would return two nodes. Remember to check the name if you want to use them by position.