Created
May 12, 2010 01:40
-
-
Save javajosh/398086 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.io.StringReader; | |
import java.util.Iterator; | |
import java.util.Map; | |
import java.util.Stack; | |
import java.util.TreeMap; | |
import org.xml.sax.Attributes; | |
import org.xml.sax.InputSource; | |
import org.xml.sax.SAXException; | |
import org.xml.sax.XMLReader; | |
import org.xml.sax.helpers.DefaultHandler; | |
import org.xml.sax.helpers.XMLReaderFactory; | |
/** | |
* Simple Expediant XML parser | |
* | |
* @author Josh Rehman <[email protected]> | |
* @date 10/13/2006 | |
*/ | |
public class SEX { | |
/** | |
* Take a small chunk of XML and parse it into nested hashtables Do not | |
* support attributes, entities, or namespaces. Do not support any | |
* non-string types (validation is assumed to occur later) | |
*/ | |
static String xml = | |
"<customer>\n" | |
+ "\t<name>Josh</name>\n" | |
+ "\t<email>[email protected]</email>\n" | |
+ "\t<address>" | |
+ "\t\t<street>123 Main Street</street>\n" | |
+ "\t\t<city>Seal Beach</city>\n" | |
+ "\t\t<state>CA</state>\n" | |
+ "\t\t<region><country>USA</country></region>\n" | |
+ "\t</address>\n" | |
+ "</customer>"; | |
public static void main(String[] args) { | |
Map result = parse(xml); | |
printMap(result, 0); | |
} | |
static void printMap(Map map, int depth){ | |
Iterator it = map.keySet().iterator(); | |
while (it.hasNext()) { | |
Object key = it.next(); | |
Object value = map.get(key); | |
if (value instanceof String) { | |
System.out.println(indent(depth) + key + ":" + value); | |
} else if (value instanceof Map) { | |
System.out.println(indent(depth) + key + ":"); | |
printMap((Map)value, depth + 1); | |
} | |
} | |
} | |
private static String indent(int depth){ | |
StringBuffer buf = new StringBuffer(); | |
buf.append(depth); | |
for (int j = 0; j < depth; j++){buf.append("\t");} | |
return buf.toString(); | |
} | |
/** | |
* Parse an xml string into some nested Maps. | |
* | |
* @param xml - a valid xml document in String form | |
* @return a nested map representing the document | |
* @see http://www.saxproject.org/quickstart.html | |
*/ | |
static Map parse(String xml) { | |
final Map result = new TreeMap(); | |
try { | |
XMLReader xr = XMLReaderFactory.createXMLReader(); | |
/** | |
* Parse a very simple XML subset into nested Maps | |
* In particular we don't support attributes or mixed content (tags and text) | |
* All tag content is trim()ed. | |
* An interesting application of recursion | |
*/ | |
xr.setContentHandler( new DefaultHandler(){ | |
String key, value; //needed especially for children. | |
Stack stack = new Stack(); //stack of maps | |
boolean isLeaf = false; | |
public void startDocument() throws SAXException { | |
stack.push(result); | |
} | |
// create a new entry in the current map, and push it on the stack | |
public void startElement(String uri, String name, String qName, Attributes atts) throws SAXException { | |
isLeaf = true; | |
key = qName; | |
Map newMap = new TreeMap(); | |
Map parentMap = (Map)stack.peek(); | |
parentMap.put(key, newMap); | |
stack.push(newMap); | |
} | |
public void endElement(String uri, String name, String qName) throws SAXException { | |
if (isLeaf) { | |
// we need to pop then peek then put! | |
// question for the class: why can't we pop twice? | |
// it messes up the stack for succeeding siblings. | |
Map newMap = (Map) stack.pop(); | |
Map parentMap = (Map) stack.peek(); | |
parentMap.put(key, value); // replaces newMap with string | |
} | |
isLeaf = false; //end elt methods called in sequence are not leaves | |
} | |
// just squirl this value away; | |
public void characters(char[] ch, int start, int length) throws SAXException { | |
value = new String(ch, start, length).trim(); | |
} | |
}); | |
xr.parse(new InputSource(new StringReader(xml))); //do it | |
} catch (SAXException e) { | |
e.printStackTrace(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
// result.put("name", "Josh"); | |
// result.put("email", "[email protected]"); | |
// | |
// Map address = new TreeMap(); | |
// address.put("street", "123 Main Street"); | |
// address.put("city", "Seal Beach"); | |
// address.put("state", "CA"); | |
// | |
// result.put("address", address); | |
return result; | |
} | |
} |
Comments are disabled for this gist.