001: /*
002: * This class provides a very primitive XM tokenizer.
003: *
004: * $Author: $
005: * $Date: $
006: * $Revision: $
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Lesser General Public
010: * License as published by the Free Software Foundation; either
011: * version 2.1 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public
019: * License along with this library; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021: *
022: * Revision History:
023: *
024: * Written by Davis Swan in April, 2005.
025: */
026: package com.sqlmagic.tinysql;
027:
028: import java.text.*;
029: import java.util.*;
030: import java.lang.*;
031:
032: public class SimpleXMLTag extends Hashtable {
033: String[] fields;
034: int fieldIndex;
035: Vector tagList;
036: int tagIndex = 0, tagEndAt;
037: String tagName, tagLabel;
038: boolean debug = false;
039:
040: /*
041: * Parse out the body text of an XML tag. The result is a string
042: * or another XMLTokenizer object. Note that if this is a child
043: * of an existing XML tag, a Vector of the tag hierarchy is passed in
044: * so that tags can be processed in the order they were encountered.
045: */
046: public SimpleXMLTag(String inputString) throws Exception {
047: this (inputString, 0, new Vector());
048: }
049:
050: public SimpleXMLTag(String inputString, int startAt,
051: Vector inputList) throws Exception {
052: char quoteChar, nextChar, bracketQuoteChar;
053: char[] charArray = { ' ' };
054: SimpleXMLTag embeddedXML;
055: int i, j, startBodyAt, endBodyAt, tagNameEndAt, embeddedTagAt;
056: String testString, bodyString;
057: tagList = inputList;
058: if (inputString.length() == 0)
059: throw new Exception("XML record is null.");
060: /*
061: * Search the body for the ending tag, ignoring everything in quotes.
062: */
063: quoteChar = ' ';
064: embeddedTagAt = -1;
065: tagName = (String) null;
066: tagNameEndAt = Integer.MIN_VALUE;
067: startBodyAt = Integer.MIN_VALUE;
068: for (i = startAt; i < inputString.length(); i++) {
069: nextChar = inputString.charAt(i);
070: if (nextChar == '\'' | nextChar == '"') {
071: if (quoteChar == ' ')
072: quoteChar = nextChar;
073: else if (nextChar == quoteChar)
074: quoteChar = ' ';
075: }
076: /*
077: * Ignore all characters in quoted strings.
078: */
079: if (quoteChar != ' ')
080: continue;
081: if (nextChar == '<') {
082: if (tagName == (String) null) {
083: /*
084: * The tag has been found. Save any text before the tag as a label.
085: */
086: tagNameEndAt = inputString.indexOf('>', i);
087: if (tagNameEndAt < 0)
088: throw new Exception("Tag is incomplete");
089: tagName = inputString
090: .substring(i + 1, tagNameEndAt);
091: if (debug)
092: System.out.println("Found tag " + tagName);
093: startBodyAt = tagNameEndAt + 1;
094: for (j = tagNameEndAt + 1; j < inputString.length(); j++) {
095: if (inputString.charAt(j) == ' ')
096: continue;
097: startBodyAt = j;
098: if (debug)
099: System.out.println("Start body at " + j);
100: break;
101: }
102: } else {
103: if (i + tagName.length() + 1 > inputString.length() - 1)
104: throw new Exception(
105: "XML record ends prematurely.");
106: /*
107: * Search for the end of the tag.
108: */
109: testString = inputString.substring(i + 1, i
110: + tagName.length() + 2);
111: if (testString.equals("/" + tagName)) {
112: endBodyAt = i - 1;
113: if (debug)
114: System.out.println("End body at "
115: + endBodyAt);
116: bodyString = inputString.substring(startBodyAt,
117: endBodyAt + 1);
118: tagEndAt = i + tagName.length() + 2;
119: if (debug)
120: System.out.println("Tag body is "
121: + bodyString);
122: put("TAG_NAME", tagName);
123: tagList.addElement(this );
124: if (embeddedTagAt > -1) {
125: /*
126: * The tag body contains one or more embedded tags
127: * which have to be parsed recursively.
128: */
129: if (embeddedTagAt > startBodyAt) {
130: tagLabel = inputString.substring(
131: startBodyAt, embeddedTagAt)
132: .trim();
133: if (tagLabel.length() > 0) {
134: if (debug)
135: System.out.println("label "
136: + tagLabel);
137: put("LABEL", tagLabel);
138: }
139: }
140: while (embeddedTagAt < endBodyAt) {
141: embeddedXML = new SimpleXMLTag(
142: inputString, embeddedTagAt,
143: tagList);
144: put(tagName, embeddedXML);
145: if (debug)
146: System.out.println("Tag "
147: + embeddedXML.tagName
148: + " ends at "
149: + embeddedXML.tagEndAt);
150: embeddedTagAt = embeddedXML.tagEndAt + 1;
151: }
152: } else {
153: put(tagName, bodyString);
154: }
155: break;
156: } else if (embeddedTagAt == -1) {
157: embeddedTagAt = i;
158: if (debug)
159: System.out.println("embeddedTagAt="
160: + embeddedTagAt);
161: }
162: }
163: }
164: }
165: }
166:
167: /*
168: * Return the total number of tags in the hierarchy.
169: */
170: public int countTags() {
171: return tagList.size();
172: }
173:
174: /*
175: * Return a particular tag by its index in the hierarchy.
176: */
177: public SimpleXMLTag getTag(int inputIndex) {
178: if (inputIndex < 0 | inputIndex > tagList.size() - 1)
179: return (SimpleXMLTag) null;
180: return (SimpleXMLTag) tagList.elementAt(inputIndex);
181: }
182:
183: /*
184: * Methods used to get tags sequentially.
185: */
186: public boolean hasMoreTags() {
187: if (tagIndex < tagList.size() - 1)
188: return true;
189: else
190: return false;
191: }
192:
193: public SimpleXMLTag nextTag() {
194: if (tagIndex > -1 & tagIndex < tagList.size() - 1) {
195: tagIndex++;
196: return (SimpleXMLTag) tagList.elementAt(tagIndex);
197: } else {
198: return (SimpleXMLTag) null;
199: }
200: }
201:
202: public String toString() {
203: Object XMLElement;
204: StringBuffer outputBuffer;
205: String tagName, objectType, tagLabel;
206: SimpleXMLTag sxml;
207: tagName = (String) get("TAG_NAME");
208: outputBuffer = new StringBuffer("<" + tagName + ">");
209: tagLabel = (String) get("LABEL");
210: if (tagLabel != (String) null)
211: outputBuffer.append(tagLabel);
212: XMLElement = get(tagName);
213: objectType = XMLElement.getClass().getName();
214: if (debug)
215: System.out.println("Tag object type is " + objectType);
216: if (objectType.endsWith("java.lang.String")) {
217: outputBuffer.append((String) XMLElement);
218: } else {
219: sxml = (SimpleXMLTag) XMLElement;
220: }
221: outputBuffer.append("\n</" + tagName + ">");
222: return outputBuffer.toString();
223: }
224: }
|