JAXB 能否以块的形式解析大型 XML 文件
我需要解析可能较大的 XML 文件,其中架构已在多个 XSD 文件中提供给我,因此 XML 绑定受到高度青睐。我想知道我是否可以使用JAXB以块的形式解析文件,如果是这样,如何解析。
我需要解析可能较大的 XML 文件,其中架构已在多个 XSD 文件中提供给我,因此 XML 绑定受到高度青睐。我想知道我是否可以使用JAXB以块的形式解析文件,如果是这样,如何解析。
因为代码很重要,所以这里有一个将大文件读成块的人。它可以以这种方式使用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();
}
}
用户指南中对此进行了详细介绍。从 http://jaxb.java.net/ 下载的 JAXB 包含一个如何一次解析一个区块的示例。
当文档很大时,通常是因为其中有重复的部分。它可能是具有大量行项目列表的采购订单,也可能是具有大量日志条目的 XML 日志文件。
这种XML适用于块处理;主要思想是使用StAX API,运行一个循环,并单独取消元帅各个块。您的程序作用于单个块,然后将其丢弃。这样,您最多只能将内存中的一个块保留,从而允许您处理大型文档。
有关如何执行此操作的详细信息,请参阅 JAXB RI 发行版中的流取消编组示例和部分取消编组示例。流式处理-取消分组示例有一个优点,它可以在任意嵌套级别处理块,但它需要您处理推送模型,--- JAXB unmarshaller 会将新块“推送”给您,您需要在那里处理它们。
相比之下,部分取消编组示例在拉模型中工作(这通常使处理更容易),但这种方法在重复部分以外的数据绑定部分有一些限制。