Все это должно быть очень прямым, но по какой-то причине это ускользает от меня.
Используя следующую структуру 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
уровень, таким образом, распечатывая все лишнее b
s … таким образом, это говорит мне о том, что основные 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.
getElementsByTagName
возвращает DOMNodeList, поэтому вам нужно повторить его, чтобы получить имена отдельных узлов:
$serials = $child->getElementsByTagName('serial') ;
foreach($serials as $serial) {
echo "\n" . $count++ . ", a" .$serial->nodeName ;
}
Как побочный узел, XML в вопросе недопустим:
<displayname> ... </displayName>
<vsys> <entry> ... </entry> </c>
Других решений пока нет …