JAXB能否以块的形式解析大型XML文件

Joh*_* F. 23 java jaxb

我需要解析可能很大的XML文件,其中的模式已经在几个XSD文件中提供给我,因此XML绑定非常受欢迎.我想知道我是否可以使用JAXB以块的形式解析文件,如果是,那么如何.

yve*_*lem 28

因为代码很重要,所以这里是一个PartialUnmarshaller将大文件读入块的人.它可以这样使用new PartialUnmarshaller<YourClass>(stream, YourClass.class)

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.*;
import java.io.InputStream;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static javax.xml.stream.XMLStreamConstants.*;

public class PartialUnmarshaller<T> {
    XMLStreamReader reader;
    Class<T> clazz;
    Unmarshaller unmarshaller;

    public PartialUnmarshaller(InputStream stream, Class<T> clazz) throws XMLStreamException, FactoryConfigurationError, JAXBException {
        this.clazz = clazz;
        this.unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
        this.reader = XMLInputFactory.newInstance().createXMLStreamReader(stream);

        /* ignore headers */
        skipElements(START_DOCUMENT, DTD);
        /* ignore root element */
        reader.nextTag();
        /* if there's no tag, ignore root element's end */
        skipElements(END_ELEMENT);
    }

    public T next() throws XMLStreamException, JAXBException {
        if (!hasNext())
            throw new NoSuchElementException();

        T value = unmarshaller.unmarshal(reader, clazz).getValue();

        skipElements(CHARACTERS, END_ELEMENT);
        return value;
    }

    public boolean hasNext() throws XMLStreamException {
        return reader.hasNext();
    }

    public void close() throws XMLStreamException {
        reader.close();
    }

    void skipElements(int... elements) throws XMLStreamException {
        int eventType = reader.getEventType();

        List<Integer> types = asList(elements);
        while (types.contains(eventType))
            eventType = reader.next();
    }
}
Run Code Online (Sandbox Code Playgroud)


ska*_*man 19

这在用户指南中有详细说明.来自http://jaxb.java.net/的JAXB下载包含一个如何一次解析一个块的示例.

当文档很大时,通常是因为文档中有重复的部分.也许这是一个包含大量订单项的采购订单,或者它可能是包含大量日志条目的XML日志文件.

这种XML适用于块处理; 主要思想是使用StAX API,运行循环,并单独解组各个块.你的程序作用于一个块,然后扔掉它.通过这种方式,您只能在内存中保留最多一个块,这样您就可以处理大型文档.

有关如何执行此操作的更多信息,请参阅JAXB RI分发中的streaming-unmarshalling示例和partial-unmarshalling示例.流式解组示例的优势在于它可以处理任意嵌套级别的块,但它需要您处理推送模型--- JAXB unmarshaller将"推送"新块并且您需要正确处理它们那里.

相比之下,部分解组示例在拉模型中工作(通常使处理更容易),但是这种方法在重复部分以外的数据绑定部分中具有一些限制.

  • 奇.你在看哪里?我刚刚从jaxb.dev.java.net/2.1.12下载了JAR,解压缩了它,"samples"下面是"partial-unmarshalling"和"stream-unmarshalling". (7认同)