Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Xpath parent node with DOMDocument PHP?

I need to get the parent of a particular node in php. I'm using DOMDocument and XPath. My XML is this:

<ProdCategories>
<ProdCategory>

    <Id>138</Id>

    <Name>Parent Category</Name>

    <SubCategories>

        <ProdCategory>

            <Id>141</Id>

            <Name>Category child</Name>

        </ProdCategory>
   </SubCategories>
</ProdCategory>
</ProdCategories>

The php code:

$dom = new DOMDocument();
$dom->load("ProdCategories_small.xml");
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//ProdCategory/Id[.="141"]/parent::*')->item(0);
print_r($nodes); 

The print is:

 DOMElement Object ( 
 [tagName] => ProdCategory [schemaTypeInfo] => [nodeName] => ProdCategory [nodeValue] => 141 Category child [nodeType] => 1 [parentNode] => (object value omitted) [childNodes] => (object value omitted) [firstChild] => (object value omitted) [lastChild] => (object value omitted) [previousSibling] => (object value omitted)

The [parentNode] is (object value omitted), why? I would get

    <Id>138</Id>

    <Name>Parent Category</Name>`
like image 860
Eliana Avatar asked Jul 10 '15 08:07

Eliana


2 Answers

The [parentNode] is (object value omitted), why?

This is because you use the print_r function and it creates such an output (via an internal helper function of the dom extension). The line in code which is creating this is:

print_r($nodes);

The string "(object value omitted)" is given by the DOMNode when either print_r or var_dump are used on it. It tells you, that the object value of that field (named parentNode) is not displayed but omitted.

From that message you could conclude that the field has a value that is an object. A simple check for the class-name could verify this:

echo get_class($nodes->parentNode), "\n"; # outputs  "DOMElement"

Compare that with fields which are an integer or an (empty) string:

[nodeType] => 1
...
[prefix] => 
[localName] => ProdCategory

So I hope this clears it up for you. Just access the field to get the parent node object:

$parent = $nodes->parentNode;

and done.

If you wonder about a certain string that PHP gives you and you have the feeling it might be something internal, you can quickly search all of PHP's codebase on http://lxr.php.net/, here is an example query for the string in your question.

like image 176
hakre Avatar answered Nov 01 '22 17:11

hakre


Just treat the xpath query nodes as filesystem paths, as mentioned here

Move up 2 nodes and get the parent and get what you need from it, such as the Id or Name.

Example:

<?php

$dom = new DOMDocument();
$dom->load("ProdCategories_small.xml");
$xpath = new DOMXPath($dom);

$parentNode = $xpath->query('//ProdCategory[Id="141"]/../..')->item(0);

$id = $xpath->query('./Id', $parentNode)->item(0);
$name = $xpath->query('./Name',$parentNode)->item(0);

print "Id: " . $id->nodeValue . PHP_EOL;
print "Name: " . $name->nodeValue . PHP_EOL;
like image 38
Alex Andrei Avatar answered Nov 01 '22 18:11

Alex Andrei