<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
<document>
    <header>
        <title>Understanding XML Tokens</title>
    </header>
    <body>
        <section>
            <title>Understanding XML Tokens</title>

            <p>An XML cursor (an instance of the
                <a href="ext:api/stable/XmlCursor">
                    <strong>XmlCursor</strong>
                </a>
                interface) moves from token to token as your code moves the cursor. When you
                move a cursor using a method such as <strong>toParent</strong>,
                <strong>toFirstAttribute</strong>, <strong>toPrevSibling</strong>,
                and so on, the cursor moves to the token fitting the description. If there
                is no appropriate token to move to, the cursor remains where it is, and
                <strong>false</strong>
                is returned to indicate that it didn't move. For example, if the cursor is
                at the ENDDOC token (the last tag in the document), a call to the
                <strong>toNextSibling</strong>
                method will not move the cursor and will return
                <strong>false</strong>
                to indicate that the move was unsuccessful.
            </p>
            <p>Note that while you can call the
                <strong>XmlCursor.currentTokenType</strong>
                method to find out which token type the cursor is at, you might find it more
                convenient to use a method such as <strong>isEnddoc</strong>.
                The <strong>XmlCursor</strong> interface provides several methods
                that make it easy to discover whether the cursor you're moving is at the token
                you're looking for. These methods, such as <strong>isStart</strong>,
                <strong>isAttr</strong>, <strong>isText</strong>,
                and so on, return a <strong>boolean</strong> value that indicates
                whether the cursor is at the token type in question.
            </p>
            <p>Tokens are represented by constants in the
                <strong>
                    <a href="ext:api/stable/XmlCursor.TokenType">TokenType</a>
                </strong>
                class, an inner class of the <strong>XmlCursor</strong> interface.
                Each has a constant you can use in switch statements to perform by-token actions.
                The following table lists the token types:
            </p>
            <table id="Table1">
                <tr>
                    <td>
                        <strong>Token Type</strong>
                    </td>
                    <td>
                        <strong>Switch Constant</strong>
                    </td>
                    <td>
                        <strong>Description</strong>
                    </td>
                </tr>
                <tr>
                    <td>STARTDOC</td>
                    <td>INT_STARTDOC</td>
                    <td>Represents the start of the XML. Always the first token. The document
                        element itself is represented by a START token, not the STARTDOC token.
                    </td>
                </tr>
                <tr>
                    <td>ENDDOC</td>
                    <td>INT_ENDDOC</td>
                    <td>Represents the end of the XML. Always the last token.</td>
                </tr>
                <tr>
                    <td>START</td>
                    <td>INT_START</td>
                    <td>Represents the start of an element.</td>
                </tr>
                <tr>
                    <td>END</td>
                    <td>INT_END</td>
                    <td>Represents the end of an element. The END token has no value, but marks
                        the element's end.
                    </td>
                </tr>
                <tr>
                    <td>TEXT</td>
                    <td>INT_TEXT</td>
                    <td>Represents text.</td>
                </tr>
                <tr>
                    <td>ATTR</td>
                    <td>INT_ATTR</td>
                    <td>Represents an attribute. ATTR tokens are allowed to appear after a STARTDOC
                        or START token.
                    </td>
                </tr>
                <tr>
                    <td>NAMESPACE</td>
                    <td>INT_NAMESPACE</td>
                    <td>Represents a namespace (xmlns) attribute. Also only allowed after START
                        or STARTDOC tokens.
                    </td>
                </tr>
                <tr>
                    <td>COMMENT</td>
                    <td>INT_COMMENT</td>
                    <td>Represents a comment.</td>
                </tr>
                <tr>
                    <td>PROCINST</td>
                    <td>INT_PROCINST</td>
                    <td>Represents a processing instruction.</td>
                </tr>
            </table>
            <p>As you use a cursor to navigate through XML, you can use one of the convenience
                methods described above to discover whether you're at the token you're looking
                for, or use the <strong>XmlCursor.currentTokenType</strong>&nbsp;method
                to discover the current token's type. The following figure illustrates example
                locations for token types:
            </p>
            <p>
                <img alt="cursor token location" src="images/conCursorTokenLocations.gif" width="727" height="532"/>
            </p>
        </section>

        <section>
            <title>Switching to Test for Token Types</title>
            <p>Here's a bit of code illustrating how you might use a Java
                <strong>switch</strong>
                statement to test for the START token type.
            </p>
            <source><![CDATA[
                // Take an incoming XmlObject and insert a cursor.
                XmlCursor documentCursor = xmlDoc.newCursor();

                /*
                 * Loop through the document, passing the cursor when it stops at each token
                 * to a function designed to discover the token type. Continue the loop
                 * as long at the cursor is at a token (until it reaches the end).
                 */
                while (!documentCursor.toNextToken().isNone()) {
                    /*
                     * Use the intValue method to return the int corresponding to the
                     * current token type. If it is the value for INT_START,
                     * then you have a match.
                     */
                    switch (cursor.currentTokenType().intValue()) {
                        case TokenType.INT_START:
                            // Print out the token type and a message.
                            System.out.println(cursor.currentTokenType() +
                            "; cursor is at the start of an element.");
                            break;
                    }
                }
                // Be sure to dispose of a cursor when you're finished.
                documentCursor.dispose();
            ]]></source>

            <p>The scope of an XML cursor is the XML document in which it is created. For
                example, you can create a cursor at the orderItem element in the example earlier
                in this topic. If you then use that
                <strong>XmlCursor</strong>
                instance's <strong>toNextToken</strong> method to move the
                cursor until it won't move any further, you'll have reached the ENDDOC token.
                In this example, that's at the
                <strong>&lt;/batchWidgetOrder&gt;</strong>
                tag. In other words, the cursor's scope is not limited to the element at which
                it was created.
            </p>
        </section>

        <section id="relatedtopics">
            <title>Related Topics</title>
            <p>
                <a href="ext:api/stable/XmlCursor.TokenType">XmlCursor.TokenType Class</a>
            </p>
            <p>
                <a href="site:cursornav">Navigating XML with Cursors</a>
            </p>
        </section>
    </body>
</document>