xml — PHP извлекает getElementsByTagName из childNodes

Все это должно быть очень прямым, но по какой-то причине это ускользает от меня.

Используя следующую структуру XML, импортированную из файла:

<locations>
<devices>
<entry>
<serial>12345</serial>
<hostname>FooBarA</hostname>
<vsys>
<entry>
<displayname>CorpA</displayName>
<tag>InternalA</tag>
</entry>
</vsys>
</c>
</entry>
<entry>
<serial>123456</serial>
<hostname>FooBarB</hostname>
<vsys>
<entry>
<displayname>CorpB</displayName>
<tag>InternalB</tag>
</entry>
</vsys>
</c>
</entry>
</devices>
</locations>

И извлечь родителя и следует прямо:

$devices = $dom->getElementsByTagName('devices');
$data = array();
foreach($devices as $node){  // each $node = <devices> == only ONE object
foreach($node->childNodes as $child) {  // each $child is the ENTIRE <entry>, including <entry> tag
// I would expect this to return the <serial> out of parent <entry>, but its not
$serial = $child->getElementsByTagName('serial') ;
echo "\n" . $count++ . ", a" .$serial->nodeName ;
if ($child->nodeName == "entry") {
// as a secondary method, I then try to extra <serial> looping through the childNodes of the parent <entry> and again, this doesn't work.
foreach ($child->childNodes as $kid) {
$serial = $kid->getElementsByTagName('serial') ;
echo ", b" .$serial->nodeName ;
}
}
}
}

Выше распечатывается:

1a, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
2a, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
3a, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
4a, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b

Мой фактический XML-файл имеет гораздо больше братьев и сестер на serial уровень, таким образом, распечатывая все лишнее bs … таким образом, это говорит мне о том, что основные foreach работают, и каждый из них правильно проходит по каждому уровню — но я не могу извлечь nodeName или getElementsByTagName в каждом уровне.

Я полагал, что один из двух методов на разных вложенных уровнях извлек бы <serial> но ни один не работает. Что мне здесь не хватает?

Я ожидаю, что это напечатало бы:

1a 12345, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
2a 123456, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
3a 1234567, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
4a 12345678, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b

Или при минимуме:

1a, b 12345, b 12345, b 12345 ...
2a, b 123456, b 123456, b 123456 ...
3a, b 1234567, b 1234567, b 1234567 ...
etc etc.

1

Решение

getElementsByTagName возвращает DOMNodeList, поэтому вам нужно повторить его, чтобы получить имена отдельных узлов:

$serials = $child->getElementsByTagName('serial') ;
foreach($serials as $serial) {
echo "\n" . $count++ . ", a" .$serial->nodeName ;
}

Как побочный узел, XML в вопросе недопустим:

  • <displayname> ... </displayName>
  • <vsys> <entry> ... </entry> </c>
1

Другие решения

Других решений пока нет …