001 package xmlBeans.cursor;
002
003 import com.bea.xml.XmlCursor;
004 import com.bea.xml.XmlCursor.TokenType;
005 import com.bea.xml.XmlObject;
006 import com.bea.xml.XmlOptions;
007
008 /**
009 * This web service illustrates how tokens correspond to portions
010 * of an XML document. A token represents a logical piece of XML, such
011 * as the start or end of an element, text, a comment, and so on. A token
012 * type, on the other hand, represents a kind of token. In other words, a token
013 * is a STARTDOC (the very beginning of an XML instance, before all markup),
014 * a START (the start of an element), a COMMENT, and so on.
015 *
016 * When navigating XML with a cursor, you move the cursor move past tokens using
017 * methods such as toNextToken, toNextElement, and so on. It's important to remember
018 * that a cursor is almost always immediately before some token. When at a START token,
019 * for example, the cursor is just before the start of an element. This also means
020 * that it is before the start of an element and after some other token. In other
021 * words, calling currentTokenType on an XmlCursor instance will usually return the
022 * token that it is immediately before. The exception to this rule is for an
023 * ENDDOC token, which is after all other markup. Because it is at the very
024 * end, it can't be before anything else.
025 *
026 * @common:target-namespace namespace="http://workshop.bea.com/TokenTypes"
027 */
028 public class TokenTypes implements com.bea.jws.WebService
029 {
030
031 /**
032 * This method accepts a well-formed XML document and loops through it to
033 * discover the token types and the XML corresponding to each token. Because whitespace
034 * is represented by the TEXT token type, some of the tokens found in the
035 * document may appear to represent nothing at all. Whitespace can occur
036 * between elements.<br/><br/>
037 *
038 * This method calls a private function that does the actual work to
039 * identify the tokens.<br/><br/>
040 *
041 * To test this method, paste the contents of the BatchOrderSimple.xml file
042 * in place of <AnyElement/> in the box provided on the Test XML of Test View.
043 *
044 * @common:operation
045 */
046 public String discoverTokenTypes(XmlObject xmlDoc) throws Exception
047 {
048 XmlCursor documentCursor = xmlDoc.newCursor();
049 StringBuffer responseBuffer = new StringBuffer();
050
051 /*
052 * Loop through the document, passing the cursor when it stops at each token
053 * to the function designed to discover the token type.
054 */
055 while (documentCursor.hasNextToken()) {
056 String tokenInfo = collectTokenTypeInfo(documentCursor) + "\n\n";
057 responseBuffer.append(tokenInfo);
058 documentCursor.toNextToken();
059 }
060 documentCursor.dispose();
061 return responseBuffer.toString();
062 }
063
064 /*
065 * Use the int value associated with each token type in a switch statement.
066 * The result is to look at each token, discover its type, and return the
067 * correct response for addition to a string buffer.
068 */
069 private String collectTokenTypeInfo(XmlCursor cursor){
070 String response = null;
071 XmlOptions options = new XmlOptions();
072
073 switch (cursor.currentTokenType().intValue()){
074
075 case TokenType.INT_STARTDOC:
076 response = cursor.currentTokenType() +
077 "; cursor is at the very beginning of the document, before any markup.";
078 break;
079
080 case TokenType.INT_START:
081 response = cursor.currentTokenType() +
082 "; cursor is just before this element's start: \n" + cursor.xmlText(options);
083 break;
084
085 case TokenType.INT_ATTR:
086 response = cursor.currentTokenType() +
087 "; cursor is just before this attribute: \n" + cursor.getTextValue();
088 break;
089
090 case TokenType.INT_TEXT:
091 response = cursor.currentTokenType() +
092 "; cursor is just before this text (may be whitespace): \n" + cursor.getChars();
093 break;
094
095 case TokenType.INT_NAMESPACE:
096 response = cursor.currentTokenType() +
097 "; cursor is just before this namespace: \n" + cursor.xmlText();
098 break;
099
100 case TokenType.INT_COMMENT:
101 response = cursor.currentTokenType() +
102 "; cursor is just before this comment: " + cursor.xmlText();
103 break;
104
105 case TokenType.INT_PROCINST:
106 response = cursor.currentTokenType() +
107 "; cursor is just before this processing instruction: " + cursor.xmlText();
108 break;
109
110 case TokenType.INT_END:
111 response = cursor.currentTokenType() +
112 "; cursor is just before the token representing an element's end.";
113 break;
114
115 case TokenType.INT_ENDDOC:
116 response = cursor.currentTokenType() +
117 "; cursor is at the end of the XML.";
118 break;
119
120 case TokenType.INT_NONE:
121 response = cursor.currentTokenType() +
122 "; cursor is not at any recognizable token; it's just before: \n " +
123 cursor.xmlText(options);
124 break;
125 default:
126 response = "Yo! Something funky happened!";
127 }
128
129 /* Return the response string. */
130 return response;
131 }
132 }
|