如果我有一些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元素上并且调用下一个(“book”)时,光标会发生什么?
</library>
并返回false。我无法弄清楚如何获取当前光标位置以便自己解决这个问题。
答案 0 :(得分:4)
查看了该函数的源代码: http://lxr.php.net/xref/PHP_5_4/ext/xmlreader/php_xmlreader.c#821
似乎指针移动到XML的末尾。
答案 1 :(得分:2)
XMLReader::next()
通过跳过所有子树节点移动到下一个节点。也就是说,它会转到与当前节点具有相同或更低 XMLReader::$depth
的下一个节点。如果没有下一个elment-node(在文档结束之后),则阅读器将停止进入下一个节点。
在您的情况下,您使用参数指定一个本地名称,在这种情况下,它不会占用所有匹配下一个节点的那些节点,而只会使用那些具有本地名称的元素节点的节点。参数。
当我的光标位于最后一个book元素上并且下一个(&#34; book&#34;)被调用时,光标会发生什么?
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')
找不到任何其他具有本地名称&#34; book
&#34;的元素节点。在到达文档末尾之前的文档中(跳过子树节点)。所以它将在文档的最后。 XMLReader::$nodeType
为XMLReader::NONE
,XMLReader::$depth
为0
。
所以在你的情况下,它会移动到文档的末尾。
- 是否保留在最后一个book元素上并返回false。
不,它不会停留。这有两个原因:首先,您调用next()
命令继续前进。所以光标位置预计会改变。其次,XMLReader没有多少状态。它只知道当前。没有 last 或 first 之类的东西。只有当前。 当前的节点类型为XMLReader::$nodeType
。如果它是XMLReader::NONE
您刚刚打开(文件开头)或者您使用了整个文档(文件结尾)。
- 是否移至
</library>
并返回false。
不,它不会移动到</library>
。这是因为您使用next()
和local-name参数。它会在没有参数的情况下移动到那里(仅$xml->next()
多次次),但是当该操作成功时,它会返回true
。
- 它还能做些什么吗?
是的,它仅仅是我上面写的内容以及XMLReader::next()
PHP manual page中记录的内容。
我无法弄清楚如何获取当前光标位置以便自己解决这个问题。
由于XMLReader只知道当前,因此维持的光标位置不多。 XMLReader仅在元素上是向前的,在元素的开始标记内只有有限的移动,读取属性然后跳回&#34;返回&#34;到元素。
有关当前节点的信息,有->nodeType
字段以及->depth
字段。
此外,您可以将光标处的节点->expand()
可视化,并将其导入DOMDocument
以将其另存为XML。但是,在您的情况下,您将在文档结束后重新开始,因此无法再展开。先检查->nodeType
字段。
我的XMLReaderIterator library on github中还有一些转储函数可用于调试节点和结构(XMLReaderNode::dump()
)。
您也可能会发现迭代器在使用XMLReader时非常有用,例如,有一个迭代器只对子项进行迭代,并在完成后停止。