Chunking XML with XMLStreamReader failing

303 views Asked by At

I am trying to chunk out a big XML into smaller pieces with StAX and JAXB. Here is the sample XML that I am working on:

<asset>
    <entity>
        <record>
            <field>
                <id>remarks</id>
                <value>ready to test1</value>
            </field>
        </record>
        <record>
            <field>
                <id>input_quarter</id>
                <value>Jun-Sep</value>
            </field>
        </record>
    </entity>
</asset>

I want to read on record at a time and process it. Here is how I am doing it:

ClassPathResource classPathResource = new ClassPathResource("samples/form2/data/test.xml");
XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, true);
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(classPathResource.getInputStream());

JAXBContext jaxbContext = JAXBContext.newInstance(EntityRecordData.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
while(xmlStreamReader.hasNext()){
    int eventType = xmlStreamReader.next();
    switch (eventType) {
    case XMLEvent.START_ELEMENT:
        System.out.println("Element: "+xmlStreamReader.getLocalName());
        if("record".equals(xmlStreamReader.getLocalName())){
            Object unmarshal = unmarshaller.unmarshal(xmlStreamReader);
        }
        break;
    case XMLEvent.CHARACTERS: 
        String text = xmlStreamReader.getText();
        System.out.println("Text: "+text);
        break;
    case XMLEvent.END_ELEMENT: 
        break;
    default : break;
    }
}
xmlStreamReader.close();

I am able to read first record properly. But after reading the first record, the stream is moving to inside the second record instead of . And hence I am not able to process the second record. I am not sure where I am going wrong. Please help.

1

There are 1 answers

0
Prasanth On BEST ANSWER

Here is the solution:

ClassPathResource classPathResource = new ClassPathResource("samples/form2/data/test.xml");
    XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
    xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, true);
    XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(classPathResource.getInputStream());

    JAXBContext jaxbContext = JAXBContext.newInstance(EntityRecordData.class);
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    int eventType = xmlStreamReader.next();
    while(true){
        switch (eventType) {
        case XMLEvent.START_ELEMENT:
            System.out.println("Element: "+xmlStreamReader.getLocalName());
            if("record".equals(xmlStreamReader.getLocalName())){
                JAXBElement<EntityRecordData> unmarshal = unmarshaller.unmarshal(xmlStreamReader, EntityRecordData.class);
                final List<IFieldData> fields = unmarshal.getValue().getFields();
                System.out.println("**"+fields.get(0).getId());
            } else {
                eventType = xmlStreamReader.next();
            }
            break;
        case XMLEvent.CHARACTERS: 
            String text = xmlStreamReader.getText();
            System.out.println("Text: "+text);
            eventType = xmlStreamReader.next();
            break;
        case XMLEvent.END_ELEMENT: 
            //System.out.println("End: "+xmlStreamReader.getLocalName());
            eventType = xmlStreamReader.next();
            break;
        default : 
            break;
        }

        if(!xmlStreamReader.hasNext()){
            break;
        }
    }
    xmlStreamReader.close();