How XmlReader :: next positions the cursor when it returns false

If I have XML like:

<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>

      

And maneuvering my cursor to the first item i of the book item using:

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

      

When my cursor is on the last element of the book and the next ("book") is called, what happens to the cursor?

  • Whether it stays on the last element of the book and returns false.
  • Whether it </library>

    will move to and return false.
  • Does this do anything else?

I can't figure out how to get the current cursor position to figure this out for myself.

+3


source to share


2 answers


By looking at the source code of this function: http://lxr.php.net/xref/PHP_5_4/ext/xmlreader/php_xmlreader.c#821



It looks like the pointer is moving to the end of the XML.

+4


source


XMLReader::next()

goes to the next node, skipping all nodes in the subtree. That is, it moves to the next node that is the same or bottom XMLReader::$depth

as the current one. If there is no subsequent elment-node (after the end of the document), the reader stops moving to the next node.

In your case, you are specifying a local name with a parameter, in which case it will not accept all those that match the following nodes, but only those that are an element-node with the specified local name in the parameter.

When my cursor is on the last element of the book and the next ("book") is called, what happens to the cursor?

  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>

      

At the current position of the cursor, next('book')

it will not find another element in the document - a node with the local name " book

" in the document (skipping nodes of the subtree) until the end of the document is reached. So it will be at the end of the document. XMLReader::$nodeType

is XMLReader::NONE

, then XMLReader::$depth

0

.

So in your case, it moves to the end of the document.

  • Whether it stays on the last element of the book and returns false.

No, he doesn't stay. This happens for two reasons: First, you are triggered next()

, which control the movement. Therefore, the location of the cursor is expected to change. Secondly, XMLReader doesn't save a lot of state. He only knows the current one. There is not something like the last or the first. There is only current. The node type is XMLReader::$nodeType

. If it is XMLReader::NONE

, you either just opened (beginning of file) or you destroyed the entire document (end of file).

  • Whether it </library>

    will move to and return false.


No, it doesn't move to </library>

. This is because you were using next()

the local-name parameter. It would have moved there without a parameter (just a $xml->next()

few times), however, since this operation would have been successful, it would have returned true

then.

  • Does this do anything else?

Yes, it just does what I wrote above and what is described in the XMLReader::next()

PHP
page .

I can't figure out how to get the current cursor position to figure this out for myself.

Since XMLReader only knows the current, not much cursor position is supported. XMLReader is only available for elements, there is only limited movement inside the open tag of the element to read the attributes and then jump "back" to the element.

For information about the current node, there is a field ->nodeType

as well as a field ->depth

.

Alternatively, you can render the node with the be cursor ->expand()

and import it in DOMDocument

to save it as XML. However, in your case, you are after the end of the document, so you can no longer expand it. Check the field first ->nodeType

.

My XMLReaderIterator library on github has a dump function which can be useful for debugging nodes and structure ( XMLReaderNode::dump()

).

You may also find that iterators are there useful when using XMLReader, for example there is an iteration that only runs on children and stops when done.

+2


source







All Articles