Php SimpleXML найти определенный дочерний узел на любом уровне в Родительском


Я использую SimpleXML для анализа моего xml-файла. Я перебираю его, и в каждом узле мне нужно получить значение одного конкретного тега. Вот пример

<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>

В каждом узле мне нужно получить тег findme. Но я не знаю, на каком уровне это может быть, все, что я знаю, это tagname

2 2

2 ответа:

Вам нужно использовать XPath, чтобы найти целевой элемент, потому что вы не знаете уровень целевого тега. Php SimpleXMLElement класс имеет xpath метод, который находит элемент по XPath.

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

Вы можете проверить результат в demo


Редактировать:

Вам нужно использовать DOMDocument класс, если вы хотите найти определенный элемент в другом элементе.

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

Вы можете проверить результат в demo

Единственное решение, которое я принял, было использовать эту рекурсивную функцию

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

Обновлено

Также, как было предложено в комментариях, мы можем использовать класс DOMDocument следующим образом:

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

 foreach($nodes as $node)
 { 
    $findme = $node->getElementsByTagName("findme")->item(0);
    echo $findme->textContent."\r";
 }