org.apache.xmlbeans.XmlCursor Maven / Gradle / Ivy
/* Copyright 2004 The Apache Software Foundation
*
* Licensed 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.
*/
package org.apache.xmlbeans;
import javax.xml.namespace.QName;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Map;
/**
* Represents a position between two logical tokens in an XML document.
*
* The tokens themselves are not exposed as objects, but their type and properties
* are discoverable through methods on the cursor. In particular, the general
* category of token is represented by a {@link XmlCursor.TokenType TokenType}.
*
* You use an XmlCursor instance to navigate through and manipulate an XML
* instance document.
* Once you obtain an XML document, you can create a cursor to represent
* a specific place in the XML. Because you can use a cursor with or
* without a schema corresponding to the XML, cursors are an ideal
* way to handle XML without a schema. You can create a new cursor by
* calling the {@link XmlTokenSource#newCursor() newCursor} method
* exposed by an object representing
* the XML, whether it was parsed into a strong type compiled from
* schema or an {@link XmlObject XmlObject} (as in the no-schema case).
*
* With an XmlCursor, you can also:
*
*
* - Execute XQuery and XPath expressions against the XML with the
* execQuery and selectPath methods.
*
* - Edit and reshape the document by inserting, moving, copying, and removing
* XML.
*
* - Insert bookmarks that "stick" to the XML at the cursor's
* position even if the cursor or XML moves.
*
* - Get and set values for containers (elements and whole documents),
* attributes, processing instructions, and comments.
*
*
* A cursor moves through XML by moving past tokens. A
* token represents a category of XML markup, such as the start of an element,
* its end, an attribute, comment, and so on. XmlCursor methods such as
* toNextToken, toNextSibling, toParent, and so on move the cursor
* among tokens. Each token's category is of a particular type, represented
* by one of the nine types defined by the {@link XmlCursor.TokenType TokenType} class.
*
* When you get a new cursor for a whole instance document, the cursor is
* intially located before the STARTDOC token. This token, which has no analogy
* in the XML specification, is present in this logical model of XML
* so that you may distinguish between the document as a whole
* and the content of the document. Terminating the document is an ENDDOC
* token. This token is also not part of the XML specification. A cursor
* located immediately before this token is at the very end of the document.
* It is not possible to position the cursor after the ENDDOC token.
* Thus, the STARTDOC and ENDDOC tokens are effectively "bookends" for the content of
* the document.
*
* For example, for the following XML, if you were the navigate a cursor
* through the XML document using toNextToken(), the list of token types that
* follows represents the token sequence you would encounter.
*
*
* <sample x='y'>
* <value>foo</value>
* </sample>
*
*
* STARTDOC
* START (sample)
* ATTR (x='y')
* TEXT ("\n ")
* START (value)
* TEXT ("foo")
* END (value)
* TEXT ("\n")
* END (sample)
* ENDDOC
*
* When there are no more tokens available, hasNextToken() returns
* false and toNextToken() returns the special token type NONE and does not move
* the cursor.
*
*
* The {@link #currentTokenType() currentTokenType()} method
* will return the type of the token that is immediately after the cursor.
* You can also use a number of convenience methods that test for a particular
* token type. These include the methods isStart(),
* isStartdoc(), isText(), isAttr(), and so on. Each returns a boolean
* value indicating whether the token that follows the cursor is the type
* in question.
*
*
* A few other methods determine whether the token is of a kind that may include
* multiple token types. The isAnyAttr() method, for example, returns true if
* the token immediately following the cursor is any kind of attribute,
* including those of the ATTR token type and xmlns attributes.
*
*
* Legitimate sequences of tokens for an XML document are described
* by the following Backus-Naur Form (BNF):
*
*
* <doc> ::= STARTDOC <attributes> <content> ENDDOC
* <element> ::= START <attributes> <content> END
* <attributes> ::= ( ATTR | NAMESPACE ) *
* <content> ::= ( COMMENT | PROCINST | TEXT | <element> ) *
*
*
* Note that a legitimate sequence is STARTDOC ENDDOC, the result of
* creating a brand new instance of an empty document. Also note that
* attributes may only follow container tokens (STARTDOC or START)
*/
public interface XmlCursor extends XmlTokenSource, AutoCloseable {
/**
* An enumeration that identifies the type of an XML token.
*/
public static final class TokenType {
public String toString() {
return _name;
}
/**
* Returns one of the INT_ values defined in this class.
*/
public int intValue() {
return _value;
}
/**
* No token. See {@link #intValue}.
*/
public static final int INT_NONE = 0;
/**
* The start-document token. See {@link #intValue}.
*/
public static final int INT_STARTDOC = 1;
/**
* The end-document token. See {@link #intValue}.
*/
public static final int INT_ENDDOC = 2;
/**
* The start-element token. See {@link #intValue}.
*/
public static final int INT_START = 3;
/**
* The end-element token. See {@link #intValue}.
*/
public static final int INT_END = 4;
/**
* The text token. See {@link #intValue}.
*/
public static final int INT_TEXT = 5;
/**
* The attribute token. See {@link #intValue}.
*/
public static final int INT_ATTR = 6;
/**
* The namespace declaration token. See {@link #intValue}.
*/
public static final int INT_NAMESPACE = 7;
/**
* The comment token. See {@link #intValue}.
*/
public static final int INT_COMMENT = 8;
/**
* The processing instruction token. See {@link #intValue}.
*/
public static final int INT_PROCINST = 9;
/**
* True if no token.
*/
public boolean isNone() {
return this == NONE;
}
/**
* True if is start-document token.
*/
public boolean isStartdoc() {
return this == STARTDOC;
}
/**
* True if is end-document token.
*/
public boolean isEnddoc() {
return this == ENDDOC;
}
/**
* True if is start-element token.
*/
public boolean isStart() {
return this == START;
}
/**
* True if is end-element token.
*/
public boolean isEnd() {
return this == END;
}
/**
* True if is text token.
*/
public boolean isText() {
return this == TEXT;
}
/**
* True if is attribute token.
*/
public boolean isAttr() {
return this == ATTR;
}
/**
* True if is namespace declaration token.
*/
public boolean isNamespace() {
return this == NAMESPACE;
}
/**
* True if is comment token.
*/
public boolean isComment() {
return this == COMMENT;
}
/**
* True if is processing instruction token.
*/
public boolean isProcinst() {
return this == PROCINST;
}
/**
* True if is start-document or start-element token
*/
public boolean isContainer() {
return this == STARTDOC || this == START;
}
/**
* True if is end-document or end-element token
*/
public boolean isFinish() {
return this == ENDDOC || this == END;
}
/**
* True if is attribute or namespace declaration token
*/
public boolean isAnyAttr() {
return this == NAMESPACE || this == ATTR;
}
/**
* The singleton no-token type
*/
public static final TokenType NONE = new TokenType("NONE", INT_NONE);
/**
* The singleton start-document token type
*/
public static final TokenType STARTDOC = new TokenType("STARTDOC", INT_STARTDOC);
/**
* The singleton start-document token type
*/
public static final TokenType ENDDOC = new TokenType("ENDDOC", INT_ENDDOC);
/**
* The singleton start-element token type
*/
public static final TokenType START = new TokenType("START", INT_START);
/**
* The singleton end-element token type
*/
public static final TokenType END = new TokenType("END", INT_END);
/**
* The singleton text token type
*/
public static final TokenType TEXT = new TokenType("TEXT", INT_TEXT);
/**
* The singleton attribute token type
*/
public static final TokenType ATTR = new TokenType("ATTR", INT_ATTR);
/**
* The singleton namespace declaration token type
*/
public static final TokenType NAMESPACE = new TokenType("NAMESPACE", INT_NAMESPACE);
/**
* The singleton comment token type
*/
public static final TokenType COMMENT = new TokenType("COMMENT", INT_COMMENT);
/**
* The singleton processing instruction token type
*/
public static final TokenType PROCINST = new TokenType("PROCINST", INT_PROCINST);
private TokenType(String name, int value) {
_name = name;
_value = value;
}
private String _name;
private int _value;
}
/**
* Deallocates resources needed to manage the cursor, rendering this cursor
* inoperable. Because cursors are managed by a mechanism which stores the
* XML, simply letting a cursor go out of scope and having the garbage collector
* attempt to reclaim it may not produce desirable performance.
*
* So, explicitly disposing a cursor allows the underlying implementation
* to release its responsibility of maintaining its position.
*
* After a cursor has been closed, it may not be used again. It can
* throw IllegalStateException or NullPointerException if used after
* disposal.
*
* XmlCursor implements java.lang.AutoCloseable
and the
* try-with-resources pattern is recommended.
*
* Note: Future major release will remove this default implementation.
*/
default void close() {
this.dispose();
}
/**
* Deallocates resources needed to manage the cursor. For details see
* {@link #close()}. XmlCursor implements java.lang.AutoCloseable
* and the try-with-resources pattern is recommended.
*
* @see #close()
*/
@Deprecated
void dispose();
/**
* Moves this cursor to the same position as the moveTo cursor. if the
* moveTo cursor is in a different document from this cursor, this cursor
* will not be moved, and false returned.
*
* @param moveTo The cursor at the location to which this cursor
* should be moved.
* @return true if the cursor moved; otherwise, false.
*/
boolean toCursor(XmlCursor moveTo);
/**
* Saves the current location of this cursor on an internal stack of saved
* positions (independent of selection). This location may be restored
* later by calling the pop() method.
*/
void push();
/**
* Restores the cursor location most recently saved with the push() method.
*
* @return true if there was a location to restore; otherwise, false.
*/
boolean pop();
/**
* Executes the specified XPath expression against the XML that this
* cursor is in. The cursor's position does not change. To navigate to the
* selections, use {@link #hasNextSelection} and {@link #toNextSelection} (similar to
* {@link java.util.Iterator}).
*
* The root referred to by the expression should be given as
* a dot. The following is an example path expression:
*
* cursor.selectPath("./purchase-order/line-item");
*
*
* Note that this method does not support top-level XPath functions.
*
* @param path The path expression to execute.
* @throws XmlRuntimeException If the query expression is invalid.
*/
void selectPath(String path);
/**
* Executes the specified XPath expression against the XML that this
* cursor is in. The cursor's position does not change. To navigate to the
* selections, use hasNextSelection and toNextSelection (similar to
* java.util.Iterator).
*
* The root referred to by the expression should be given as
* a dot. The following is an example path expression:
*
* cursor.selectPath("./purchase-order/line-item");
*
*
* Note that this method does not support top-level XPath functions.
*
* @param path The path expression to execute.
* @param options Options for the query. For example, you can call
* the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)}
* method to specify a particular name for the query expression
* variable that indicates the context node.
* @throws XmlRuntimeException If the query expression is invalid.
*/
void selectPath(String path, XmlOptions options);
/**
* Returns whether or not there is a next selection.
*
* @return true if there is a next selection; otherwise, false.
*/
boolean hasNextSelection();
/**
* Moves this cursor to the next location in the selection,
* if any. See the {@link #selectPath} and {@link #addToSelection} methods.
*
* @return true if the cursor moved; otherwise, false.
*/
boolean toNextSelection();
/**
* Moves this cursor to the specified location in the selection.
* If i is less than zero or greater than or equal to the selection
* count, this method returns false.
*
* See also the selectPath() and addToSelection() methods.
*
* @param i The index of the desired location.
* @return true if the cursor was moved; otherwise, false.
*/
boolean toSelection(int i);
/**
* Returns the count of the current selection. See also the selectPath()
* and addToSelection() methods.
*
* You may experience better performance if you use the iteration
* model using the toNextSelection method, rather than
* the indexing model using the getSelectionCount and
* toSelection methods.
*
* @return A number indicating the size of the current selection.
*/
int getSelectionCount();
/**
* Appends the current location of the cursor to the selection.
* See also the selectPath() method. You can use this as an
* alternative to calling the selectPath method when you want
* to define your own selection.
*/
void addToSelection();
/**
* Clears this cursor's selection, but does not modify the document.
*/
void clearSelections();
/**
* Moves this cursor to the same position as the bookmark. If the
* bookmark is in a different document from this cursor or if the
* bookmark is orphaned, this cursor
* will not be moved, and false will be returned.
*
* @param bookmark The bookmark at the location to which this
* cursor should be moved.
* @return true if the cursor moved; otherwise, false.
*/
boolean toBookmark(XmlBookmark bookmark);
/**
* Moves this cursor to the location after its current position
* where a bookmark with the given key exists. Returns false if no
* such bookmark exists.
*
* @param key The key held by the next bookmark at the location to
* which this cursor should be moved.
* @return The next corresponding bookmark, if it exists; null if there
* is no next bookmark with the specified key.
*/
XmlBookmark toNextBookmark(Object key);
/**
* Moves this cursor to the location before its current position
* where a bookmark with the given key exists. Returns false if no
* such bookmark exists.
*
* @param key The key held by the previous bookmark at the location to
* which this cursor should be moved.
* @return The previous corresponding bookmark, if it exists; null if
* there is no previous bookmark with the specified key.
*/
XmlBookmark toPrevBookmark(Object key);
/**
* Returns the name of the current token. Names may be associated with
* START, ATTR, NAMESPACE or PROCINST. Returns null if there is no
* name associated with the current token. For START and ATTR, the
* name returned identifies the name of the element or attribute.
* For NAMESPACE, the local part of the name is the prefix, while
* the URI is the namespace defined. For PROCINST, the local part
* is the target and the uri is "".
*
* In the following example, {@code xmlObject} represents
* an XML instance whose root element is not preceded by any other XML.
* This code prints the root element name (here, the local name, or
* name without URI).
*
* XmlCursor cursor = xmlObject.newCursor();
* cursor.toFirstContentToken();
* String elementName = cursor.getName().getLocalPart();
* System.out.println(elementName);
*
*
* @return The name of the XML at this cursor's location; null if there
* is no name.
*/
QName getName();
/**
* Sets the name of the current token. This token can be START, NAMESPACE,
* ATTR or PROCINST.
*
* @param name The new name for the current token.
*/
void setName(QName name);
/**
* Returns the namespace URI indicated by the given prefix. The current
* context must be at a START or STARTDOC. Namespace prefix mappings
* are queried for the mappings defined at the current container first,
* then parents are queried. The prefix can be "" or null to indicate
* a search for the default namespace. To conform with the
* XML spec, the default namespace will return the no-namespace ("")
* if it is not mapped.
*
* Note that this queries the current state of the document. When the
* document is persisted, the saving mechanism may synthesize namespaces
* (ns1, ns2, and so on) for the purposes of persistence. These namepaces are
* only present in the serialized form, and are not reflected back into
* the document being saved.
*
* @param prefix The namespace prefix for the requested namespace.
* @return The URI for corresponding to the specified prefix if it
* exists; otherwise, null.
*/
String namespaceForPrefix(String prefix);
/**
* Returns a prefix that can be used to indicate a namespace URI. The
* current context must be at a START or STARTDOC. If there is an
* existing prefix that indicates the URI in the current context, that
* prefix may be returned. Otherwise, a new prefix for the URI will be
* defined by adding an xmlns attribute to the current container or a
* parent container.
*
* Note that this queries the current state of the document. When the
* document is persisted, the saving mechanism may synthesize namespaces
* (ns1, ns2, and so on) for the purposes of persistence. These namepaces are
* only present in the serialized form, and are not reflected back into
* the document being saved.
*
* @param namespaceURI The namespace URI corresponding to the requested
* prefix.
* @return The prefix corresponding to the specified URI if it exists;
* otherwise, a newly generated prefix.
*/
String prefixForNamespace(String namespaceURI);
/**
* Adds to the specified map, all the namespaces in scope at the container
* where this cursor is positioned. This method is useful for
* container tokens only.
*
* @param addToThis The Map to add the namespaces to.
*/
void getAllNamespaces(Map addToThis);
/**
* Returns the strongly-typed XmlObject at the current START,
* STARTDOC, or ATTR.
*
* The strongly-typed object can be cast to the strongly-typed
* XBean interface corresponding to the XML Schema Type given
* by result.getSchemaType().
*
* If a more specific type cannot be determined, an XmlObject
* whose schema type is anyType will be returned.
*
* @return The strongly-typed object at the cursor's current location;
* null if the current location is not a START, STARTDOC, or ATTR.
*/
XmlObject getObject();
/**
* Returns the type of the current token. By definition, the current
* token is the token immediately to the right of the cursor.
* If you're in the middle of text, before a character, you get TEXT.
* You can't dive into the text of an ATTR, COMMENT or PROCINST.
*
* As an alternative, it may be more convenient for you to use one of the
* methods that test for a particular token type. These include the methods
* isStart(), isStartdoc(), isText(), isAttr(), and so on. Each returns a boolean
* value indicating whether the token that follows the cursor is the type
* in question.
*
*
* @return The TokenType instance for the token at the cursor's current
* location.
*/
TokenType currentTokenType();
/**
* True if the current token is a STARTDOC token type, meaning
* at the very root of the document.
*
* @return true if this token is a STARTDOC token type;
* otherwise, false.
*/
boolean isStartdoc();
/**
* True if this token is an ENDDOC token type, meaning
* at the very end of the document.
*
* @return true if this token is an ENDDOC token type;
* otherwise, false.
*/
boolean isEnddoc();
/**
* True if this token is a START token type, meaning
* just before an element's start.
*
* @return true if this token is a START token type;
* otherwise, false.
*/
boolean isStart();
/**
* True if this token is an END token type, meaning
* just before an element's end.
*
* @return true if this token is an END token type;
* otherwise, false.
*/
boolean isEnd();
/**
* True if the this token is a TEXT token type, meaning
* just before or inside text.
*
* @return true if this token is a TEXT token type;
* otherwise, false.
*/
boolean isText();
/**
* True if this token is an ATTR token type, meaning
* just before an attribute.
*
* @return true if this token is an ATTR token type;
* otherwise, false.
*/
boolean isAttr();
/**
* True if this token is a NAMESPACE token type, meaning
* just before a namespace declaration.
*
* @return true if this token is a NAMESPACE token type;
* otherwise, false.
*/
boolean isNamespace();
/**
* True if this token is a COMMENT token type, meaning
* just before a comment.
*
* @return true if this token is a COMMENT token type;
* otherwise, false.
*/
boolean isComment();
/**
* True if this token is a PROCINST token type, meaning
* just before a processing instruction.
*
* @return true if this token is a PROCINST token type;
* otherwise, false.
*/
boolean isProcinst();
/**
* True if this token is a container token. The STARTDOC and START
* token types are containers. Containers, including documents and elements,
* have the same content model. In other words, a document and an element
* may have the same contents. For example, a document may contain attributes
* or text, without any child elements.
*
* @return true if this token is a container token; otherwise, false.
*/
boolean isContainer();
/**
* True if this token is a finish token. A finish token can be an ENDDOC
* or END token type.
*
* @return true if this token is a finish token; otherwise, false.
*/
boolean isFinish();
/**
* True if this token is any attribute. This includes an ATTR token type and
* the NAMESPACE token type attribute.
*
* @return true if the current cursor is at any attribute; otherwise, false.
*/
boolean isAnyAttr();
/**
* Returns the type of the previous token. By definition, the previous
* token is the token immediately to the left of the cursor.
*
* If you're in the middle of text, after a character, you get TEXT.
*
* @return The TokenType instance for the token immediately before the
* token at the cursor's current location.
*/
TokenType prevTokenType();
/**
* True if there is a next token. When this is false, as when the cursor is
* at the ENDDOC token, the toNextToken() method returns NONE and does not
* move the cursor.
*
* @return true if there is a next token; otherwise, false.
*/
boolean hasNextToken();
/**
* True if there is a previous token. When this is false, toPrevToken
* returns NONE and does not move the cursor.
*
* @return true if there is a previous token; otherwise, false.
*/
boolean hasPrevToken();
/**
* Moves the cursor to the next token. When there are no more tokens
* available, hasNextToken returns false and toNextToken() returns
* NONE and does not move the cursor. Returns the token type
* of the token to the right of the cursor upon a successful move.
*
* @return The token type for the next token if the cursor was moved;
* otherwise, NONE.
*/
TokenType toNextToken();
/**
* Moves the cursor to the previous token. When there is no
* previous token, returns NONE, otherwise returns the token
* to the left of the new position of the cursor.
*
* @return The token type for the previous token if the cursor was moved;
* otherwise, NONE.
*/
TokenType toPrevToken();
/**
* Moves the cursor to the first token in the content of the current
* START or STARTDOC. That is, the first token after all ATTR and NAMESPACE
* tokens associated with this START.
*
* If the current token is not a START or STARTDOC, the cursor is not
* moved and NONE is returned. If the current START or STARTDOC
* has no content, the cursor is moved to the END or ENDDOC token.
*
* @return The new current token type.
*/
TokenType toFirstContentToken();
/**
* Moves the cursor to the END or ENDDOC token corresponding to the
* current START or STARTDOC, and returns END or ENDDOC.
*
* If the current token is not a START or STARTDOC, the cursor is not
* moved and NONE is returned.
*
* @return The new current token type.
*/
TokenType toEndToken();
/**
* Moves the cursor forward by the specified number of characters, and
* stops at the next non-TEXT token. Returns the number of characters
* actually moved across, which is guaranteed to be less than or equal to
* maxCharacterCount. If there is no further text, or if
* there is no text at all, returns zero.
*
* Note this does not dive into attribute values, comment contents,
* processing instruction contents, etc., but only content text.
*
* You can pass maxCharacterCount < 0 to move over all the text to the
* right. This has the same effect as toNextToken, but returns the amount
* of text moved over.
*
* @param maxCharacterCount The maximum number of characters by which
* the cursor should be moved.
* @return The actual number of characters by which the cursor was moved;
* 0 if the cursor was not moved.
*/
int toNextChar(int maxCharacterCount);
/**
* Moves the cursor backwards by the number of characters given. Has
* similar characteristics to the {@link #toNextChar(int) toNextChar} method.
*
* @param maxCharacterCount The maximum number of characters by which
* the cursor should be moved.
* @return The actual number of characters by which the cursor was moved;
* 0 if the cursor was not moved.
*/
int toPrevChar(int maxCharacterCount);
/**
* Moves the cursor to the next sibling element, or returns
* false and does not move the cursor if there is no next sibling
* element. (By definition the position of an element is the same
* as the position of its START token.)
*
* If the current token is not s START, the cursor will be
* moved to the next START without moving out of the scope of the
* current element.
*
* @return true if the cursor was moved; otherwise, false.
*/
boolean toNextSibling();
/**
* Moves the cursor to the previous sibling element, or returns
* false and does not move the cursor if there is no previous sibling
* element. (By definition the position of an element is the same
* as the position of its START token.)
*
* @return true if the cursor was moved; otherwise, false.
*/
boolean toPrevSibling();
/**
* Moves the cursor to the parent element or STARTDOC, or returns
* false and does not move the cursor if there is no parent.
*
* Works if you're in attributes or content. Returns false only if at
* STARTDOC. Note that the parent of an END token is the corresponding
* START token.
*
* @return true if the cursor was moved; false if the cursor is at the STARTDOC
* token.
*/
boolean toParent();
/**
* Moves the cursor to the first child element, or returns false and
* does not move the cursor if there are no element children.
*
* If the cursor is not currently in an element, it moves into the
* first child element of the next element.
*
* @return true if the cursor was moved; otherwise, false.
*/
boolean toFirstChild();
/**
* Moves the cursor to the last element child, or returns false and
* does not move the cursor if there are no element children.
*
* @return true if the cursor was moved; otherwise, false.
*/
boolean toLastChild();
/**
* Moves the cursor to the first child element of the specified name in
* no namespace.
*
* @param name The name of the element to move the cursor to.
* @return true if the cursor was moved; otherwise, false.
*/
boolean toChild(String name);
/**
* Moves the cursor to the first child element of the specified name in the
* specified namespace.
*
* @param namespace The namespace URI for the element to move the cursor
* to.
* @param name The name of the element to move to.
* @return true if the cursor was moved; otherwise, false.
* @throws IllegalArgumentException If the name is not a valid local name.
*/
boolean toChild(String namespace, String name);
/**
* Moves the cursor to the first child element of the specified qualified name.
*
* @param name The name of the element to move the cursor to.
*/
boolean toChild(QName name);
/**
* Moves the cursor to the child element specified by index.
*
* @param index The position of the element in the sequence of child
* elements.
* @return true if the cursor was moved; otherwise, false.
*/
boolean toChild(int index);
/**
* Moves the cursor to the specified index child element of the
* specified name, where that element is the .
*
* @param name The name of the child element to move the cursor to.
* @param index The position of the element in the sequence of child
* elements.
* @return true if the cursor was moved; otherwise, false.
*/
boolean toChild(QName name, int index);
/**
* Moves the cursor to the next sibling element of the specified name in no
* namespace.
*
* @param name The name of the element to move the cursor to.
* @return true if the cursor was moved; otherwise, false.
*/
boolean toNextSibling(String name);
/**
* Moves the cursor to the next sibling element of the specified name
* in the specified namespace.
*
* @param namespace The namespace URI for the element to move the cursor
* to.
* @param name The name of the element to move the cursor to.
* @return true if the cursor was moved; otherwise, false.
*/
boolean toNextSibling(String namespace, String name);
/**
* Moves the cursor to the next sibling element of the specified
* qualified name.
*
* @param name The name of the element to move the cursor to.
* @return true if the cursor was moved; otherwise, false.
*/
boolean toNextSibling(QName name);
/**
* Moves the cursor to the first attribute of this element, or
* returns false and does not move the cursor if there are no
* attributes. The order of attributes is arbitrary, but stable.
*
* If the cursor is on a STARTDOC of a document-fragment, this method will
* move it to the first top level attribute if one exists.
*
* xmlns attributes (namespace declarations) are not considered
* attributes by this function.
*
* The cursor must be on a START or STARTDOC (in the case of a
* document fragment with top level attributes) for this method to
* succeed.
*
* Example for looping through attributes:
*
{@code
* XmlCursor cursor = ... //cursor on START or STARTDOC
* if (cursor.toFirstAttribute())
* {
* do
* {
* // do something using attribute's name and value
* cursor.getName();
* cursor.getTextValue();
* }
* while (cursor.toNextAttribute());
* }
* }
*
* @return true if the cursor was moved; otherwise, false.
*/
boolean toFirstAttribute();
/**
* Moves the cursor to the last attribute of this element, or
* returns false and does not move the cursor if there are no
* attributes. The order of attributes is arbitrary, but stable.
*
* xmlns attributes (namespace declarations) are not considered
* attributes by this function.
*
* The cursor must be on a START or STARTDOC for this method
* to succeed.
*
* @return true if the cursor was moved; otherwise, false.
*/
boolean toLastAttribute();
/**
* Moves the cursor to the next sibling attribute, or returns
* false and does not move the cursor if there is no next
* sibling attribute. The order of attributes is arbitrary, but stable.
*
* xmlns attributes (namespace declarations) are not considered
* attributes by this function.
*
* The cursor must be on an attribute for this method to succeed.
*
* @return true if the cursor was moved; otherwise, false.
* @see #toFirstAttribute()
*/
boolean toNextAttribute();
/**
* Moves the cursor to the previous sibling attribute, or returns
* false and does not move the cursor if there is no previous
* sibling attribute. The order of attributes is arbitrary, but stable.
*
* xmlns attributes (namespace declarations) are not considered
* attributes by this function.
*
* The cursor must be on an attribute for this method to succeed.
*
* @return true if the cursor was moved; otherwise, false.
*/
boolean toPrevAttribute();
/**
* When at a START or STARTDOC, returns the attribute text for the given
* attribute. When not at a START or STARTDOC or the attribute does not
* exist, returns null.
*
* @param attrName The name of the attribute whose value is requested.
* @return The attribute's value if it has one; otherwise, null.
*/
String getAttributeText(QName attrName);
/**
* When at a START or STARTDOC, sets the attribute text for the given
* attribute. When not at a START or STARTDOC returns false.
* If the attribute does not exist, one is created.
*
* @param attrName The name of the attribute whose value is being set.
* @param value The new value for the attribute.
* @return true if the new value was set; otherwise, false.
*/
boolean setAttributeText(QName attrName, String value);
/**
* When at a START or STARTDOC, removes the attribute with the given name.
*
* @param attrName The name of the attribute that should be removed.
* @return true if the attribute was removed; otherwise, false.
*/
boolean removeAttribute(QName attrName);
/**
* Gets the text value of the current document, element, attribute,
* comment, procinst or text token.
*
* When getting the text value of an element, non-text content such
* as comments and processing instructions are ignored and text is concatenated.
* For elements that have nested element children, this
* returns the concatenated text of all mixed content and the
* text of all the element children, recursing in first-to-last
* depthfirst order.
*
* For attributes, including namespaces, this returns the attribute value.
*
* For comments and processing instructions, this returns the text content
* of the comment or PI, not including the delimiting sequences <!-- -->, <? ?>.
* For a PI, the name of the PI is also not included.
*
* The value of an empty tag is the empty string.
*
* If the current token is END or ENDDOC, this throws an {@link java.lang.IllegalStateException}.
*
* @return The text value of the current token if the token's type is
* START, STARTDOC, TEXT, ATTR, COMMENT, PROCINST, or NAMESPACE; null
* if the type is NONE.
*/
String getTextValue();
/**
* Copies the text value of the current document, element, attribute,
* comment, processing instruction or text token, counting right from
* this cursor's location up to maxCharacterCount,
* and copies the returned text into returnedChars.
*
* When getting the text value of an element, non-text content such
* as comments and processing instructions are ignored and text is concatenated.
* For elements that have nested element children, this
* returns the concatenated text of all mixed content and the
* text of all the element children, recursing in first-to-last
* depthfirst order.
*
* For attributes, including namespaces, this returns the attribute value.
*
* For comments and processing instructions, this returns the text contents
* of the comment or PI, not including the delimiting sequences <!-- -->, <? ?>. For
* a PI, the text will not include the name of the PI.
*
* If the current token is END or ENDDOC, this throws an {@link java.lang.IllegalStateException}.
*
* The value of an empty tag is the empty string.
*
* @param returnedChars A character array to hold the returned characters.
* @param offset The position within returnedChars to which the first of the
* returned characters should be copied.
* @param maxCharacterCount The maximum number of characters after this cursor's
* location to copy. A negative value specifies that all characters should be copied.
* @return The actual number of characters copied; 0 if no characters
* were copied.
*/
int getTextValue(char[] returnedChars, int offset, int maxCharacterCount);
/**
* Sets the text value of the XML at this cursor's location if that XML's
* token type is START, STARTDOC, ATTR, COMMENT or PROCINST.
*
* For elements that have nested children this first removes all
* the content of the element and replaces it with the given text.
*
* @param text The text to use as a new value.
* @throws java.lang.IllegalStateException If the token type at this
* cursor's location is not START, STARTDOC, ATTR, COMMENT or
* PROCINST.
*/
void setTextValue(String text);
/**
* Sets the text value of the XML at this cursor's location (if that XML's
* token type is START, STARTDOC, ATTR, COMMENT or PROCINST) to the
* contents of the specified character array.
*
* For elements that have nested children this first removes all
* the content of the element and replaces it with the given text.
*
* @param sourceChars A character array containing the XML's new value.
* @param offset The position within sourceChars from which the first of
* the source characters should be copied.
* @param length The maximum number of characters to set as the XML's new
* value.
* @throws java.lang.IllegalArgumentException If the token type at this
* cursor's location is not START, STARTDOC, ATTR, COMMENT or
* PROCINST.
*/
void setTextValue(char[] sourceChars, int offset, int length);
/**
* Returns characters to the right of the cursor up to the next token.
*/
String getChars();
/**
* Copies characters up to the specified maximum number, counting right from
* this cursor's location to the character at maxCharacterCount. The
* returned characters are added to returnedChars, with the first
* character copied to the offset position. The maxCharacterCount
* parameter should be less than or equal to the length of returnedChars
* minus offset. Copies a number of characters, which is
* either maxCharacterCount or the number of characters up to the next token,
* whichever is less.
*
* @param returnedChars A character array to hold the returned characters.
* @param offset The position within returnedChars at which the first of the
* returned characters should be added.
* @param maxCharacterCount The maximum number of characters after this cursor's
* location to return.
* @return The actual number of characters returned; 0 if no characters
* were returned or if the current token is not TEXT.
*/
int getChars(char[] returnedChars, int offset, int maxCharacterCount);
/**
* Moves the cursor to the STARTDOC token, which is the
* root of the document.
*/
void toStartDoc();
/**
* Moves the cursor to the ENDDOC token, which is the end
* of the document.
*/
void toEndDoc();
/**
* Determines if the specified cursor is in the same document as
* this cursor.
*
* @param cursor The cursor that may be in the same document
* as this cursor.
* @return true if the specified cursor is in the same document;
* otherwise, false.
*/
boolean isInSameDocument(XmlCursor cursor);
/**
* Returns an integer indicating whether this cursor is before,
* after, or at the same position as the specified cursor.
*
* {@code a.comparePosition(b) < 0} means a is to the left of b.
* {@code a.comparePosition(b) == 0} means a is at the same position as b.
* {@code a.comparePosition(b) > 0} means a is to the right of b.
*
* The sort order of cursors in the document is the token order.
* For example, if cursor "a" is at a START token and the cursor "b"
* is at a token within the contents of the same element, then
* a.comparePosition(b) will return -1, meaning that the position
* of a is before b.
*
* @param cursor The cursor whose position should be compared
* with this cursor.
* @return 1 if this cursor is after the specified cursor; 0 if
* this cursor is at the same position as the specified cursor;
* -1 if this cursor is before the specified cursor.
* @throws java.lang.IllegalArgumentException If the specified
* cursor is not in the same document as this cursor.
*/
int comparePosition(XmlCursor cursor);
/**
* Determines if this cursor is to the left of (or before)
* the specified cursor. Note that this is the same as
* {@code a.comparePosition(b) < 0 }
*
* @param cursor The cursor whose position should be compared
* with this cursor.
* @return true if this cursor is to the left of the specified
* cursor; otherwise, false.
*/
boolean isLeftOf(XmlCursor cursor);
/**
* Determines if this cursor is at the same position as
* the specified cursor. Note that this is the same as
* {@code a.comparePosition(b) == 0 }
*
* @param cursor The cursor whose position should be compared
* with this cursor.
* @return true if this cursor is at the same position as
* the specified cursor; otherwise, false.
*/
boolean isAtSamePositionAs(XmlCursor cursor);
/**
* Determines if this cursor is to the right of (or after)
* the specified cursor. Note that this is the same as
* {@code a.comparePosition(b) > 0 }
*
* @param cursor The cursor whose position should be compared
* with this cursor.
* @return true if this cursor is to the right of the specified
* cursor; otherwise, false.
*/
boolean isRightOf(XmlCursor cursor);
/**
* Executes the specified XQuery expression against the XML this
* cursor is in.
*
* The query may be a String or a compiled query. You can precompile
* an XQuery expression using the XmlBeans.compileQuery method.
*
* The root referred to by the expression should be given as
* a dot. The following is an example path expression:
*
* XmlCursor results = cursor.execQuery("purchase-order/line-item[price <= 20.00]");
*
*
* @param query The XQuery expression to execute.
* @return A cursor containing the results of the query.
* @throws XmlRuntimeException If the query expression is invalid.
*/
XmlCursor execQuery(String query);
/**
* Executes the specified XQuery expression against the XML this
* cursor is in, and using the specified options.
*
* @param query The XQuery expression to execute.
* @param options Options for the query. For example, you can call
* the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)}
* method to specify a particular name for the query expression
* variable that indicates the context node.
* @throws XmlRuntimeException If the query expression is invalid.
*/
XmlCursor execQuery(String query, XmlOptions options);
/**
* Represents the state of a dcoument at a particular point
* in time. It is used to determine if a document has been changed
* since that point in time.
*/
interface ChangeStamp {
/**
* Returns whether or not the document assoiated with this ChangeStamp
* has been altered since the ChangeStamp had been created.
*/
public boolean hasChanged();
}
/**
* Returns the current change stamp for the document the current cursor is in.
* This change stamp can be queried at a later point in time to find out
* if the document has changed.
*
* @return The change stamp for the document the current cursor is in.
*/
ChangeStamp getDocChangeStamp();
/**
* Subclasses of XmlBookmark can be used to annotate an XML document.
* This class is abstract to prevent parties from inadvertently
* interfering with each others' bookmarks without explicitly
* sharing a bookmark class.
*/
abstract class XmlBookmark {
/**
* Constructs a strongly-referenced bookmark.
*/
public XmlBookmark() {
this(false);
}
/**
* Constructs a bookmark.
*
* @param weak true if the document's reference to the bookmark should be a WeakReference
*/
public XmlBookmark(boolean weak) {
_ref = weak ? new WeakReference(this) : null;
}
/**
* Call the createCursor method to create a new cursor which is
* positioned at the same splace as the bookmark. It is much more
* efficient to call toBookmark on an existing cursor than it
* is to create a new cursor. However, toBookmark may fail if the
* bookmark is in a different document than the cursor. It is
* under these circumstances where createCursor needs to be called
* on the bookmark. Subsequent navigations to bookmark
* positions should attempt to reuse the last cursor to
* improve performace.
*
* @return the new cursor
*/
public final XmlCursor createCursor() {
return _currentMark == null ? null : _currentMark.createCursor();
}
/**
* @param c the cursor to be moved
* @return the given cursor moved to this bookmark
*/
public final XmlCursor toBookmark(XmlCursor c) {
return c == null || !c.toBookmark(this) ? createCursor() : c;
}
/**
* The default key for bookmarks is the class which implements
* them. This way, multiple parties using bookmarks in the
* same instance document will not interfere with eachother.
* One can, however, override getKey() to use a key other than
* the class.
*
* @return default key for bookmarks
*/
public Object getKey() {
return this.getClass();
}
/**
* The mark is set by the host document; it is capable of
* returning an XmlCursor implementation at the location of
* the bookmark.
*/
public XmlMark _currentMark;
/**
* If non-null, the ref is used by the host document
* to maintain a reference to the bookmark. If it is a weak
* reference, the host document will not prevent the Bookmark
* from being garbage collected.
*/
public final Reference _ref;
}
/**
* An abstract {@link XmlCursor} factory.
* Implementations of XmlCursor implement XmlMark to be able to
* reconstitute a cursor from a bookmark. When content moves between
* implementations, the XmlMark is set to the implmentation's which
* receives the new content.
*/
interface XmlMark {
XmlCursor createCursor();
}
/**
* Sets a bookmark to the document at this cursor's location.
*
* The bookmark is attached to the token in the tree immediately
* after the cursor. If the tree is manipulated to move
* that object to a different place, the bookmark moves with it.
* If the tree is manipulated to delete that token from the
* tree, the bookmark is orphaned. Copy operations do not copy
* bookmarks.
*
* @param bookmark The bookmark to set.
*/
void setBookmark(XmlBookmark bookmark);
/**
* Retrieves the bookmark with the specified key
* at this cursor's location. If there is no bookmark whose key is
* given by the specified key at the current position, null is returned.
* If the {@link XmlCursor.XmlBookmark#getKey() getKey} method is not overridden on
* the bookmark, then the bookmark's class is used as the key.
*
* @param key The key for the bookmark to retrieve.
* @return The requested bookmark; null if there is no bookmark
* corresponding to the specified key.
*/
XmlBookmark getBookmark(Object key);
/**
* Clears the bookmark whose key is specified, if the bookmark
* exists at this cursor's location.
*
* @param key The for the bookmark to clear.
*/
void clearBookmark(Object key);
/**
* Retrieves all the bookmarks at this location, adding them to
* the specified collection. Bookmarks held by weak references are
* added to this collection as Weak referenced objects pointing to the
* bookmark.
*
* @param listToFill The collection that will contain bookmarks
* returned by this method.
*/
void getAllBookmarkRefs(Collection