【问题标题】:How does XmlReader::next position the cursor when it returns falseXmlReader::next 返回false时如何定位光标
【发布时间】:2014-10-23 15:36:29
【问题描述】:

如果我有一些 XML,例如:

<library>
    <books>
        <book>
            <title>book #1</title>
        </book>
        <book>
            <title>book #2</title>
        </book>
    </books>
    <authors>
         <author>
             <name>author #1</name>
         </author>
         <author>
             <name>author #2</name>
         </author>
    </authors>
</library>

将光标移动到我循环使用的第一个书籍元素:

do {
    //...
} while($xml->next("book"));

当我的光标位于最后一个 book 元素上并调用 next("book") 时,光标会发生什么情况?

  • 它是否停留在最后一个 book 元素并返回 false。
  • 是否移动到 &lt;/library&gt; 并返回 false。
  • 它还有其他作用吗?

我无法弄清楚如何获取当前光标位置来自己解决这个问题。

【问题讨论】:

    标签: php xml xmlreader


    【解决方案1】:

    查看了该函数的源代码: http://lxr.php.net/xref/PHP_5_4/ext/xmlreader/php_xmlreader.c#821

    看起来指针移动到了 XML 的末尾。

    【讨论】:

      【解决方案2】:

      XMLReader::next() 通过跳过所有子树节点移动到下一个节点。也就是说,它会转到与当前节点具有相同或更低 XMLReader::$depth 的下一个节点。如果没有下一个元素节点(在文档结尾之后),阅读器将停止前往下一个节点。

      在您的情况下,您使用参数指定了本地名称,在这种情况下,它不会采用所有匹配的下一个节点,而只会采用那些具有在参数。

      当我的光标位于最后一个 book 元素上并调用 next("book") 时,光标会发生什么情况?

        cursor is currently here
                  |
                  v
                  <book>
                      <title>book #2</title>
                  </book>
              </books>
              <authors>
                   <author>
                       <name>author #1</name>
                   </author>
                   <author>
                       <name>author #2</name>
                   </author>
              </authors>
          </library>
      

      从当前光标位置,next('book') 在到达文档末尾之前不会在文档中找到任何其他具有本地名称“book”的元素节点(跳过子树节点)。所以它将在文档的末尾。那么XMLReader::$nodeType 就是XMLReader::NONE,那么XMLReader::$depth 就是0

      因此,在您的情况下,它会移动到文档的末尾。

      • 它是否停留在最后一个 book 元素并返回 false。

      不,它不会留下来。这有两个原因:首先,您调用了next() 哪些命令可以继续。所以光标位置预计会改变。其次,XMLReader 不保留太多状态。它只知道当前。没有像 lastfirst 这样的东西。只有当前current 的节点类型是XMLReader::$nodeType。如果是XMLReader::NONE,您要么刚刚打开(文件开头),要么使用了整个文档(文件结尾)。

      • 是否移动到 &lt;/library&gt; 并返回 false。

      不,它不会移动到&lt;/library&gt;。那是因为您将 next() 与 local-name 参数一起使用。如果没有参数,它会移动到那里(只是$xml-&gt;next() 多次 次),但是由于该操作会成功,所以它会返回true

      • 它还有其他作用吗?

      是的,它仅执行我上面写的以及XMLReader::next() PHP manual page 中记录的内容。

      我无法弄清楚如何获取当前光标位置来自己解决这个问题。

      由于 XMLReader 只知道 当前,因此没有多少光标位置被维护。 XMLReader 在元素上是只进的,在元素的开始标签内只有有限的移动,读取属性然后“返回”到元素。

      关于当前节点的信息,有-&gt;nodeType字段,还有-&gt;depth字段。

      此外,您可以将光标处的节点可视化为-&gt;expand()ing,并将其导入DOMDocument 以将其保存为XML。但是,在您的情况下,您在文档结束之后,因此您无法再展开。然后先检查-&gt;nodeType 字段。

      我的XMLReaderIterator library on github 中还有一些转储函数,可用于调试节点和结构 (XMLReaderNode::dump())。

      您还可能会发现那里的迭代器在使用 XMLReader 时很有用,例如,有一个迭代器只对子级进行迭代并在完成后停止。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-24
        • 1970-01-01
        • 2021-02-18
        • 2021-07-22
        • 2014-07-09
        • 1970-01-01
        相关资源
        最近更新 更多