XMLReader 跳过父节点

XMLReader Skip Parent Node

来自the documentation

The XMLReader extension is an XML pull parser. The reader acts as a cursor going forward on the document stream and stopping at each node on the way

我想去下一个但是父节点<group>阻止了我。

XML 结构

<group name="blabla">
 <o>
  <id>Value</id>
  <name>Value</name>
  <category>Value</category>
 </o>
 <o>
  <id>Value</id>
  <name>Value</name>
  <category>Value</category>
 </o>
 <o>
  <id>Value</id>
  <name>Value</name>
  <category>Value</category>
 </o>
</group>
<group name="blabla">
 <o>
  <id>Value</id>
  <name>Value</name>
  <category>Value</category>
 </o>
 <o>
  <id>Value</id>
  <name>Value</name>
  <category>Value</category>
 </o>
 <o>
  <id>Value</id>
  <name>Value</name>
  <category>Value</category>
 </o>
</group> etc..

我想去下一个但是父节点阻止我。

<?php
$reader = new XMLReader();
$reader->open($fileTMP);

while (true) {
    if ($reader->nodeType === XMLReader::ELEMENT
        && $reader->name === XML_PRODUCT_ELEMENT_NAME
        && $reader->isEmptyElement === false) {

        $item = simplexml_load_string($reader->readOuterXML(), null, LIBXML_NOCDATA);

        $product = [];
        $product['id'] = trim((string) $item->id);
        $product['name'] = trim((string) $item->name);

        if (isset($item->imgs->i)) {
            foreach ($item->imgs as $image) {
                $product['foto'][] = trim((string) $image->i['url']);
            }
        }

        if (!$reader->next(XML_PRODUCT_ELEMENT_NAME)) {
            break;
        }
    } else if (!$reader->read()) {
        break;
    }
}

$reader->close();

我认为你的主要问题是当你到达

     if (!$reader->next(XML_PRODUCT_ELEMENT_NAME)) {
         break;
     }

您可能一直在读取一系列 <o> 元素,然后当第一组完成时,它会到达这里,看看它不是 <o> 元素并从阅读循环。所以先评论out/delete这段代码

然后为确保它通读文档,更改

       elseif (!$reader->read()) {

       if (!$reader->read()) {

这意味着如果您没有 <o> 元素并跳过任何不相关的节点,此代码将始终在主循环中运行。

简单更好

$reader = new XMLReader();
$reader->open($fileTMP);

while ($reader->read()) {
 if ($reader->nodeType === XMLReader::ELEMENT && $reader->name === XML_PRODUCT_ELEMENT_NAME && $reader->isEmptyElement === false) {
     $item = simplexml_load_string($reader->readOuterXML(), null, LIBXML_NOCDATA);

     $product = [];
     $product['id'] = trim((string) $item->id);
     $product['name'] = trim((string) $item->name);

     if (isset($item->imgs->i)) {
         foreach ($item->imgs as $image) {
             $product['foto'][] = trim((string) $image->i['url']);
         }
     }    
 }
}
$reader->close();