Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* ************************************************************************
  #
  #  DivConq
  #
  #  http://divconq.com/
  #
  #  Copyright:
  #    Copyright 2014 eTimeline, LLC. All rights reserved.
  #
 #  License:
 #    See the license.txt file in the project's top-level directory for details.
 #
 #  Authors:
 #    * Andy White
 #
 ************************************************************************ */
 package divconq.xml;
 
 import java.io.Reader;
 import java.util.Map;
 
Quick and Dirty XML parser. This parser is, like the SAX parser, an event based parser, but with much less functionality. Based off of QDParser by Kevin Twidle see http://twicom.com/
 
 public class XmlParser {
 	private static int popMode(Stack<Integerst) {
 		if (!st.empty())
 			return st.pop().intValue();
 		return ;
 	}
 
 	private final static int TEXT = 1, ENTITY = 2, OPEN_TAG = 3, CLOSE_TAG = 4,
 			START_TAG = 5, ATTRIBUTE_LVALUE = 6, ATTRIBUTE_EQUAL = 9,
 			ATTRIBUTE_RVALUE = 10, QUOTE = 7, IN_TAG = 8, SINGLE_TAG = 12,
 			COMMENT = 13, IGNORE = 14, PRE = 15, CDATA = 16,
 
 	/*
 	 * Parses XML from a reader and returns a data structure containing the
 	 * parsed XML.
 	 * 
 	 * @param doc
 	 *            the DocHandler that will be given the different elements of
 	 *            the XML
 	 * @param reader
 	 *            the Reader to get the source XML from
 	 * @throws XMLParseException
 	 *             if an error in the XML is detected
 	 * @throws IOException
 	 *             if an error using the Reader is detected
 	 */
 	public static OperationResult parse(IParseHandler docReader reader) {
 		
 		try {
 			Stack<Integerst = new Stack<Integer>();
 			int depth = 0;
 			int mode = ;
 			int c = 0;
 			int quotec = '"';
 			depth = 0;
 			StringBuffer sb = new StringBuffer();
 			StringBuffer etag = new StringBuffer();
 			String tagName = null;
 			String lvalue = null;
 			String rvalue = null;
 			Map<StringStringattrs = null;
 			
 			doc.startDocument(or);
 			
 			if (or.hasErrors())
 				return or;
 			
 			int line = 1, col = 0;
 			boolean eol = false;
 	
 			// TODO add support for surrogate pair, set String Builder 32
 			while ((c = reader.read()) != -1) {
 				// We need to map \r, \r\n, and \n to \n
 				// See XML spec section 2.11
 				if (c == '\n' && eol) {
 					eol = false;
 					continue;
 				} 
 				else if (eol) {
 					eol = false;
 				} 
 				else if (c == '\n') {
 					line++;
 					col = 0;
				else if (c == '\r') {
					eol = true;
					c = '\n';
					line++;
					col = 0;
				else {
					col++;
				}
				if (mode == ) {
					// We are between tags collecting text.
					if (c == '<') {
						st.push(new Integer(mode));
						mode = ;
						if (sb.length() > 0) {
							doc.text(orsb.toString(), falselinecol);
							if (or.hasErrors())
								return or;
							sb.setLength(0);
						}
					else if (c == '&') {
						st.push(new Integer(mode));
						mode = ;
						etag.setLength(0);
					else
						sb.append((charc);
				else if (mode == ) {
					// we are processing a closing tag: e.g. </foo>
					if (c == '>') {
						mode = popMode(st);
						tagName = sb.toString();
						sb.setLength(0);
						depth--;
						doc.endElement(ortagName);
						if (or.hasErrors())
							return or;
						if (depth == 0) {
							doc.endDocument(or);
							return or;
						}
					else {
						sb.append((charc);
					}
				else if (mode == ) {
					// we are processing CDATA
					if (c == '>' && sb.toString().endsWith("]]")) {
						sb.setLength(sb.length() - 2);
						doc.text(orsb.toString(), truelinecol);
						if (or.hasErrors())
							return or;
						sb.setLength(0);
						mode = popMode(st);
					else
						sb.append((charc);
				else if (mode == ) {
					// we are processing a comment. We are inside
					// the <!-- .... --> looking for the -->.
					if (c == '>' && sb.toString().endsWith("--")) {
						sb.setLength(0);
						mode = popMode(st);
					else
						sb.append((charc);
				else if (mode == ) {
					// We are outside the root tag element
					if (c == '<') {
						mode = ;
						st.push(new Integer(mode));
						mode = ;
					}
				else if (mode == ) {
					// We are inside one of these <? ... ?>
					// or one of these <!DOCTYPE ... >
					if (c == '>') {
						mode = popMode(st);
						if (mode == )
							mode = ;
					}
				else if (mode == ) {
					// we have just seen a < and
					// are wondering what we are looking at
					// <foo>, </foo>, <!-- ... --->, etc.
					mode = popMode(st);
					if (c == '/') {
						st.push(new Integer(mode));
						mode = ;
					else if (c == '?') {
						mode = ;
					else if (c == '!') {
						st.push(new Integer(mode));
						tagName = null;
						attrs = new Hashtable<StringString>();
						sb.append((charc);
					else if (c == '_' || Character.isLetter(c)) {
						st.push(new Integer(mode));
						mode = ;
						tagName = null;
						attrs = new Hashtable<StringString>();
						sb.append((charc);
					else {
						or.errorTr(242, linecol, (charc);
						return or;
					}
				else if (mode == ) {
					// we are processing an entity, e.g. &lt;, &#187;, etc.
					if (c == ';') {
						mode = popMode(st);
						String cent = etag.toString();
						etag.setLength(0);
						/*
						if (cent.equals("lt"))
							sb.append('<');
						else if (cent.equals("gt"))
							sb.append('>');
						else if (cent.equals("amp"))
							sb.append('&');
						else if (cent.equals("quot"))
							sb.append('"');
						else if (cent.equals("apos"))
							sb.append('\'');
						else if (cent.startsWith("#x"))
							sb.append((char) Integer.parseInt(cent.substring(2), 16));
						else if (cent.startsWith("#"))
							sb.append((char) Integer.parseInt(cent.substring(1)));
						else {
							// Just keep the unknown entity
							sb.append('&');
							sb.append(cent);
							sb.append(';');
							// exc("Unknown entity: &" + cent + ";", line, col);
						}
						*/
						// APW Just keep the entity
						sb.append('&');
						sb.append(cent);
						sb.append(';');
					else {
						etag.append((charc);
					}
				else if (mode == ) {
					// we have just seen something like this:
					// <foo a="b"/
					// and are looking for the final >.
					if (tagName == null)
						tagName = sb.toString();
					if (c != '>') {
						or.errorTr(241, linecoltagName);
						return or;
					}
					doc.element(ortagNameattrslinecol);
					//doc.endElement(tagName);
					if (or.hasErrors())
						return or;
					if (depth == 0) {
						doc.endDocument(or);
						return or;
					}
					sb.setLength(0);
					attrs = new HashMap<StringString>();
					tagName = null;
					mode = popMode(st);
				else if (mode == ) {
					// we are processing <!... >.
					// We already have the first character
					if (c == '>') {
						or.errorTr(241, linecolsb.toString());
						return or;
					else if (c == '-' && sb.toString().equals("!-")) {
						mode = ;
					else if (c == '[' && sb.toString().equals("![CDATA")) {
						mode = ;
						sb.setLength(0);
					else if (c == 'E' && sb.toString().equals("!DOCTYP")) {
						sb.setLength(0);
						mode = ;
					else if (Character.isWhitespace((charc)) {
						or.errorTr(240, linecolsb.toString());
						return or;
					else {
						// We have a character to add to the instruction
						// Check for length
						if (sb.length() > 9) {
							or.errorTr(239, linecolsb.toString());
							return or;
						}
						// Check for validity
						if (c == '-' || c == '[' || Character.isLetter(c))
							sb.append((charc);
						else {
							or.errorTr(238, linecolcsb.toString());
							return or;
						}
					}
				else if (mode == ) {
					// we are processing something
					// like this <foo ... >.
					// We already have the first character
					if (c == '>') {
						if (tagName == null)
							tagName = sb.toString();
						sb.setLength(0);
						depth++;
						doc.startElement(ortagNameattrslinecol);
						if (or.hasErrors())
							return or;
						tagName = null;
						attrs = new HashMap<StringString>();
						mode = popMode(st);
					else if (c == '/') {
						mode = ;
					else if (Character.isWhitespace((charc)) {
						tagName = sb.toString();
						sb.setLength(0);
						mode = ;
					else {
						// We have a character to add to the name
						// Check for validity
						if (Character.isLetterOrDigit(c) || c == '_' || c == '-'
								|| c == '.' || c == ':')
							sb.append((charc);
						else {
							or.errorTr(237, linecolc);
							return or;
						}
					}
				}
				else if (mode == ) {
					// We are processing the quoted right-hand side
					// of an element's attribute.
					if (c == quotec) {
						rvalue = sb.toString();
						sb.setLength(0);
						attrs.put(lvaluervalue);
						mode = ;
						// See section the XML spec, section 3.3.3
						// on normalization processing.
					else if (" \r\n\u0009".indexOf(c) >= 0) {
						sb.append(' ');
					else if (c == '&') {
						st.push(new Integer(mode));
						mode = ;
						etag.setLength(0);
					else {
						sb.append((charc);
					}
				else if (mode == ) {
					if (c == '"' || c == '\'') {
						quotec = c;
						mode = ;
					else if (Character.isWhitespace((charc)) {
						;
					else {
						or.errorTr(236, linecol);
						return or;
					}
				else if (mode == ) {
					if (Character.isWhitespace((charc)) {
						lvalue = sb.toString();
						sb.setLength(0);
					else if (c == '=') {
						lvalue = sb.toString();
						sb.setLength(0);
					else {
						sb.append((charc);
					}
				else if (mode == ) {
					if (c == '=') {
					else if (Character.isWhitespace((charc)) {
						;
					else {
						or.errorTr(235, linecol);
						return or;
					}
				else if (mode == ) {
					if (c == '>') {
						mode = popMode(st);
						doc.startElement(ortagNameattrslinecol);
						if (or.hasErrors())
							return or;
						depth++;
						tagName = null;
						attrs = new HashMap<StringString>();
					else if (c == '/') {
						mode = ;
					else if (Character.isWhitespace((charc)) {
						;
					else {
						sb.append((charc);
					}
				}
			}
			if (mode != )
				or.errorTr(234, linecol);
			return or;
		}
		catch (IOException x) {
			or.error("Erroring reading XML: " + x);
		}
		finally {
			IOUtil.closeQuietly(reader);
		}
		return or;
	}
New to GrepCode? Check out our FAQ X