Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does JAXB advance the XMLStreamReader?

Tags:

java

xml

jaxb

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?

like image 361
dalelane Avatar asked Jul 03 '14 10:07

dalelane


1 Answers

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.

like image 62
bdoughan Avatar answered Sep 27 '22 22:09

bdoughan