首页 > 解决方案 > Stax 解析两次

问题描述

我正在尝试使用 stax 从下面的 xml 中获取父母,请注意,同一结构中可以有多个父母和孩子。

<sm:Structure>
    <sm:Parent>
         <sm:parentCode>PARENT-CODE-1</sm:parentCode>
         <sm:parentName>PARENT-NAME-1</sm:parentName>
     </sm:Parent>
     <sm:Child>
         <sm:childCode>CHILD-CODE-1</sm:childCode>
         <sm:childName>CHILD-NAME-1</sm:childName>
         <sm:parentCode>PARENT-CODE-1</sm:parentCode>
     </sm:Child>
 </sm:Structure>

使用以下代码:

XMLStreamReader xmlr = null;
try {
    XMLInputFactory xmlif = XMLInputFactory.newInstance();
    File file = new File(fileName);
    xmlr = xmlif.createXMLStreamReader(new FileReader(file));

    JAXBContext context = JAXBContext.newInstance(type);
    Unmarshaller unmarshaller = context.createUnmarshaller();

    while (xmlr.hasNext() && (!xmlr.isStartElement() || !xmlr.getLocalName().equalsIgnoreCase(localName))) {
        xmlr.next();
    }

    List<T> objectList = new ArrayList<>();
    int numberOfRead = 0, chunkIndex = 0;

    StopWatch watch = new StopWatch();
    watch.start();
    while (xmlr.getEventType() == XMLStreamConstants.START_ELEMENT) {
        if (numberOfRead == chunkSize) {
            chunkConsumer.consumeChunk(objectList, chunkIndex, chunkSize, breakChildProcessOnParentError));
            numberOfRead = 0;
            chunkIndex++;
            objectList = new ArrayList<>();
        }
        JAXBElement<T> objNode = unmarshaller.unmarshal(xmlr, type);
        T obj = objNode.getValue();
        objectList.add(obj);
        numberOfRead++;

        if (xmlr.getEventType() == XMLStreamConstants.CHARACTERS) {
            xmlr.next();
        }
    }
    if (numberOfRead != 0) {
        chunkConsumer.consumeChunk(objectList, chunkIndex, chunkSize, breakChildProcessOnParentError));
    }
    watch.stop();
    log.info("Time Elapsed to trigger all " + type.getName() + "-Chunk-Consumers: " + 
    watch.toSplitString());
} catch (Exception e) {
    throw new CustomException("Error during " + type.getName()+ "-Chunk-Consumer process.", e);
} finally {
    try {
        if (xmlr != null) {
            xmlr.close();
        }
    } catch (Exception exception) {
        log.error(exception.getMessage(), exception);
    }
}

它有趣地读取了两次父母,第一次没问题,第二次没有 parentName。为什么要解析两次?

标签: javaxmlxml-parsingstax

解决方案


在一段时间内错过了一个条件,添加解决了我的问题。

while (xmlr.getEventType() == XMLStreamConstants.START_ELEMENT && xmlr.getLocalName().equalsIgnoreCase(localName)) {

推荐阅读