0

I have trouble getting the value of the 'qt' child node of a selected 'item'.

XML

<cart>
    <item>
        <id>3</id>
        <qt>101</qt>
        <yourBid>88</yourBid>
    </item>
</cart>

PHP

$xml = new DomDocument('1.0');
$xml->load('cart.xml');
$xpath = new DOMXPATH($xml);

$id = 3;

foreach($xpath->query("/cart/item[id='$id']") as $node)
{
    // $qt=$node->qt;
    // $qt=$node->children(0)->getName;
}

I've tried with these 2 methods but it doesn't seem to work.

$qt=$node->qt;

ERROR MESSAGE

Fatal error: Uncaught Error: Call to undefined method DOMElement::children() in C:\wamp64\www\test\test.php on line 12

Error: Call to undefined method DOMElement::children() in C:\wamp64\www\test\test.php on line 12

$qt=$node->children(0)->getName;

ERROR MESSAGE

Notice: Undefined property: DOMElement::$qt in C:\wamp64\www\test\test.php on line 11

Jaz
  • 3
  • 2
  • Do you have access to change the XML or have to use the schema provided? – hppycoder Mar 25 '21 at 20:47
  • Welcome to StackOverflow. Please edit your question and describe what "doesn't seem to work" means. Do you get an error message (what is the message)? Is the output unexpected (what is the expected output)? You can find more tips in the [How To Ask](https://stackoverflow.com/help/how-to-ask) section. – Petr Hejda Mar 25 '21 at 21:03

2 Answers2

1

You can extend the xpath query to get the qt element adding /qt to it and then get the nodeValue.

$xml = new DomDocument('1.0');
$xml->load('cart.xml');
$xpath = new DOMXPATH($xml);
$id = 3;
foreach($xpath->query("//cart/item[id='$id']/qt") as $node)
{
     echo $node->nodeValue;
}

Output

101

Another option is to loop the childnodes and check for the nodeName

foreach($xpath->query("//cart/item[id='$id']") as $node) {
    foreach($node->childNodes as $child) {
        if ($child->nodeName === "qt") {
            echo $child->nodeValue;
        }
    }    
}
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
1

If you use DOMXpath::evaluate() you can use a string cast inside the Xpath expression to fetch the contents of a node.

foreach($xpath->evaluate("/cart/item[id='$id']") as $item) {
    var_dump($xpath->evaluate('string(qt)', $item));
}

Or you let the expression iterate over the qt elements and read DOMNode::$textContent:

foreach ($xpath->evaluate("/cart/item[id='$id']/qt") as $qt) {
    var_dump($qt->textContent);
}

Or if here is only a single matching node fetch the value without the loop using the string typecast:

var_dump($xpath->evaluate("string(/cart/item[id='$id']/qt)");
ThW
  • 19,120
  • 3
  • 22
  • 44