使用XMLStreamReader的Chunking XML失败

时间:2015-06-16 10:46:25

标签: java xml jaxb stax

我正在尝试使用StAX和JAXB将大型XML分成小块。以下是我正在处理的示例XML:

<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>

我想一次阅读记录并处理它。我是这样做的:

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();

我能够正确阅读第一条记录。但是在读完第一条记录之后,流正在转移到第二条记录内,而不是。因此我无法处理第二条记录。我不确定我哪里出错了。请帮忙。

1 个答案:

答案 0 :(得分:0)

以下是解决方案:

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();