Anna
Anna

Reputation: 3141

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

Upvotes: 7

Views: 4547

Answers (3)

qwertynik
qwertynik

Reputation: 128

Had been looking for the same. After some tinkering, realized that the following would work.

$parent->xpath('.//findme')

Here, . means current level, and // implies anywhere within the current level/node.

Upvotes: 1

Mohammad
Mohammad

Reputation: 21499

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

Upvotes: 4

Anna
Anna

Reputation: 3141

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";
 }

Upvotes: 5

Related Questions