【问题标题】:PHP XML child parsing issuePHP XML子解析问题
【发布时间】:2017-04-25 22:30:04
【问题描述】:

这让我发疯了。在我的 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 ;
    }
  }
}

【问题讨论】:

    标签: php xml domdocument getelementsbytagname child-nodes


    【解决方案1】:

    您可以使用 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
    }
    

    【讨论】:

    • 我终于让它工作了,但它很难看。将使用您上面的建议。但是,是否可以从 childNode 中提取 getElementsByTagName?我在原始帖子的底部添加了更多示例代码。
    • 您可以在任何 DomElement 对象上使用 getElementsByTagName。但是,如果您还有其他问题,您应该在进行一些故障排除和测试后将其作为一个问题发布。
    猜你喜欢
    • 2013-05-20
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多