PHP XML 子解析问题

PHP XML child parsing issue

这让我抓狂。在我的 XML 文件中,我嵌套了同名 <entry> 的子级,并且我试图只获取顶层。如果我调用 getElementsByTagName() 它会抓住所有这些,所以我正在为直接子级解析并且似乎没有任何工作正常。

<locations>
  <devices>
    <entry>
      <a/>
      <b/>
      <c>
        <entry>
        ..
        </entry>
      </c>
    </entry>
    <entry>
      <a/>
      <b/>
      <c>
        <entry>
        ..
        </entry>
      </c>
    </entry>
  </devices>
</locations>

<?
$path = "Export.txt" ;
$xml = file_get_contents( $path );
$dom = new DOMDocument( '1.0', 'utf-8' );
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;

// use it as a source
$dom->loadXML($xml) ;

// grab all "devices" should ONLY be 1 device
$devices = $dom->getElementsByTagName('devices');

$entries = array() ;
// parse through each FIRST child...which should be the first level <entry>
// however, the below is empty.
for ($i = 0; $i < $devices->childNodes->length; ++$i) {
    echo $count++ ;
    $entries[] = $devices->childNodes->item($i);
}

// but I get the following error on this foreach:
// Warning: Invalid argument supplied for foreach() in process.php
foreach ($devices->childNodes as $node) {
    echo "This: " . $count++ ;
}

// this prints "1": which is correct.
echo sizeof($devices) ;

//关于从 childNode 中提取 getElementsByTag 的额外问题

foreach ($devices as $device) { 
  foreach($device->childNodes as $child) { // this should be each parent <entry>
    $thisC = $child->getElementsByTagName('c') ;  // this should be only <c> tags BUT THIS NEVER SEEMS TO WORK
    foreach ($thisC->childNodes as $subEntry) {
      echo $subEntry->nodeValue ;
    }
  }
}

您可以使用 XPath 查询来获取相关元素:

<?php
$dom = new DomDocument("1.0", "utf-8");
$dom->loadXML(file_get_contents("export.txt"));
$xpath = new DomXPath($dom);
$entries = $xpath->query("/locations/devices/entry");
$count = 0;
// $entries is a DomNodeList
var_dump($entries);
foreach ($entries as $entry) {
    //do stuff with $entry
}

或者,使用您原来的方法:

<?php
$dom = new DomDocument("1.0", "utf-8");
$dom->loadXML(file_get_contents("export.txt"));
$devices = $dom->getElementsByTagName('devices');
$entries = [];
foreach ($devices as $device) {
    foreach ($device->childNodes as $child) {
        if ($child instanceof DomElement && $child->tagName === "entry") {
            $entries[] = $child;
        }
    }
}
// $entries is an array of DomElement
var_dump($entries);
foreach ($entries as $entry) {
    //do stuff with $entry
}