PHP XML子解析问题

PHP XML子解析问题,php,xml,domdocument,getelementsbytagname,child-nodes,Php,Xml,Domdocument,Getelementsbytagname,Child Nodes,这让我快发疯了。在我的XML文件中,我嵌套了同名的子项,并且我只尝试获取顶层。如果我调用getElementsByTagName,它会捕获所有的元素,因此我正在解析直接子元素,似乎没有任何东西能够正常工作 <locations> <devices> <entry> <a/> <b/> <c> <entry> .. &l

这让我快发疯了。在我的XML文件中,我嵌套了同名的子项,并且我只尝试获取顶层。如果我调用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) ;
//关于从子节点提取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
}

我终于让它工作了,但它很难看。我们将使用上面您的建议。但是,是否可以从子节点提取getElementsByTagName?我在我的原始帖子的底部添加了更多的示例代码。您可以在任何DomeElement对象上使用getElementsByTagName。但是,如果您有其他问题,您应该在完成一些故障排除和测试后将其作为一个问题发布。