How does JAXB advance the XMLStreamReader?

java, jaxb, xml

Solution

Double check which element event you are on after the unmarshal call. If the `XMLStreamReader` is on `endElement` you will need to call `next()` as part of your loop, but it's on `startElement` you won't.

Problem

I'm using JAXB to unmarshal objects from very large XML files using an XMLStreamReader. If the XML elements I'm unmarshalling are separated (by a newline or even a single space) this works fine. If the XML elements I'm unmarshalling do not have whitespace between them, I lose every other item - the XML reader seems to swallow the element after the one that gets unmarshalled. Source for a simplified runnable example that demonstrates this is at https://gist.github.com/dalelane/88df784c3cb74b214d5c The interesting bits are: ``` XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream); JAXBContext context = JAXBContext.newInstance(MyJAXBClass.class); Unmarshaller unmarshaller = context.createUnmarshaller(); boolean running = true; while (running){ switch (reader.next()){ case XMLStreamConstants.START_ELEMENT: if (reader.getLocalName().equals("myunmarshallobjname")){ JAXBElement<MyJAXBClass> unmarshalledObj = unmarshaller.unmarshal(reader, MyJAXBClass.class); MyJAXBClass item = unmarshalledObj.getValue(); } break; case XMLStreamConstants.END_DOCUMENT: reader.close(); running = false; break; } } ``` Every time the stream reader hits the start of an element, I pass it to the unmarshaller to unmarshall that fragment. It works if I have XML with: ``` <myunmarshallobjname key="one"></myunmarshallobjname> <myunmarshallobjname key="two"></myunmarshallobjname> ``` But loses items if I have: ``` <myunmarshallobjname key="one"></myunmarshallobjname><myunmarshallobjname key="two"></myunmarshallobjname> ``` What am I doing wrong? How do I get the reader to not skip over elements?

Original source