Skip to content

Instantly share code, notes, and snippets.

@agentgt
Created September 19, 2012 20:54
Show Gist options
  • Save agentgt/3752190 to your computer and use it in GitHub Desktop.
Save agentgt/3752190 to your computer and use it in GitHub Desktop.
Turn XML Stream into an Object Iterator
package com.snaphop.util;
import static com.google.common.base.Preconditions.checkState;
import java.io.Reader;
import java.util.Iterator;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import com.google.common.base.Throwables;
import com.google.common.collect.AbstractIterator;
public class XmlStreamObjectUtils {
public static <T> Iterator<T> readXml(final Reader reader, final Class<T> type, final String tag, boolean skipRoot) {
// set up a StAX reader
final XMLStreamReader xmlr;
XMLStreamReader xmlrTmp = null;
final Unmarshaller unmarshaller;
try {
XMLInputFactory xmlif = XMLInputFactory.newInstance();
xmlrTmp = xmlif.createXMLStreamReader(reader);
xmlr = xmlrTmp;
final JAXBContext ucontext = JAXBContext.newInstance(type);
unmarshaller = ucontext.createUnmarshaller();
while (skipRoot && xmlr.getEventType() == XMLStreamConstants.START_DOCUMENT) {
xmlr.nextTag();
xmlr.nextTag();
}
} catch (FactoryConfigurationError e1) {
close(xmlrTmp);
throw Throwables.propagate(e1);
} catch (XMLStreamException e1) {
close(xmlrTmp);
throw Throwables.propagate(e1);
} catch (JAXBException e1) {
close(xmlrTmp);
throw Throwables.propagate(e1);
}
return new AbstractIterator<T>() {
@Override
protected T computeNext() {
try {
final XMLStreamReader x = xmlr;
while (isNotValid(x, tag)) {
if (x.getEventType() == XMLStreamConstants.START_DOCUMENT) {
x.nextTag();
}
else {
x.next();
}
}
if (x.getEventType() == XMLStreamConstants.END_DOCUMENT) {
x.close();
return endOfData();
}
checkState(xmlr.getEventType() == XMLStreamConstants.START_ELEMENT, "Expected a start element.");
JAXBElement<T> pt = unmarshaller.unmarshal(xmlr, type);
return pt.getValue();
} catch (XMLStreamException e) {
close(xmlr);
throw Throwables.propagate(e);
} catch (JAXBException e) {
close(xmlr);
throw Throwables.propagate(e);
}
}
private boolean isNotValid(final XMLStreamReader xmlr, final String tag) {
boolean hasTag = (xmlr.getEventType() == XMLStreamConstants.START_ELEMENT
&& (tag == null || tag.equals(xmlr.getLocation())));
return ! hasTag && xmlr.getEventType() != XMLStreamConstants.START_ELEMENT
&& xmlr.getEventType() != XMLStreamConstants.END_DOCUMENT;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
close(xmlr);
}
};
}
public static void close(XMLStreamReader reader) {
if (reader != null) {
try {
reader.close();
} catch (XMLStreamException e) {
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment