Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Php SimpleXML find specific child node in any level in the parent

I'm using SimpleXML to parse my xml file. I'm looping through it and in each node I need to get value of one specific tag. Here is an example

<node>
    <child1></child1>
    <findme></findme>
    <child2></child2>
</node>
<node>
    <child1>
        <findme></findme>
    </child1>
    <child2></child2>
</node>
<node>
    <child1></child1>
    <child2>
      <another>
            <findme></findme>
      </another>
    </child2>
</node>

In each node I need to get findme tag. But I don't know in which level it can be, all I know is a tagname

like image 309
Anna Avatar asked Nov 01 '16 15:11

Anna


2 Answers

The only decision I came up with was to use this recursive function

foreach($xml as $prod){
  ...
  $findme = getNode($prod, 'fabric');
  ...
}

function getNode($obj, $node) {
    if($obj->getName() == $node) { 
        return $obj;
    }
    foreach ($obj->children() as $child) {
        $findme = getNode($child, $node);
        if($findme) return $findme;
    }
}

Updated

Also as was suggested in comments we can use DOMDocument class like this:

 $dom = new DOMDocument();
 $dom->LoadXML($xmlStr);
 $nodes = $dom->getElementsByTagName('node');

 foreach($nodes as $node)
 { 
    $findme = $node->getElementsByTagName("findme")->item(0);
    echo $findme->textContent."\r";
 }
like image 155
Anna Avatar answered Oct 01 '22 03:10

Anna


You need to use XPath to find target element because you don't know level of target tag. Php SimpleXMLElement class has xpath method that find element by XPath.

$xml = new SimpleXMLElement($xmlStr);
$result = $xml->xpath('//findme');
foreach($result as $elem)
{ 
    echo $elem;
}

You can check result in demo


Edit:

You need to use DOMDocument class if you want to find specific element in another element.

$dom = new DOMDocument();
$dom->loadXML($xmlStr);
$nodes = $dom->getElementsByTagName('node');
foreach($nodes as $node)
{ 
   echo $node->getElementsByTagName("findme")->item(0)->textContent;
}

You can check result in demo

like image 29
Mohammad Avatar answered Oct 01 '22 03:10

Mohammad