Hy, 我有一個非常大的XML文件(100GB),其中包含foo列表,我想將它轉換爲類似於他們的流到java 8的對象:如何將大型XML文件轉換爲對象的流式樣java8
任何想法的lib或代碼示例?
開頭:
<foos>
<foo>...</foo>
<foo>...</foo>
</foos>
末:
Stream<Foo> foosStream = ????("foo.xml")
streamFoos.forEach(foo->foo.doFooStuffs());
編輯: @Pierre感謝你,這裏是你的解決方案的實施:
try {
XMLEventReader reader = XMLInputFactory.newInstance().
createXMLEventReader(stream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(XXXXX.class).createUnmarshaller();
Iterator<XXXXX> it = new XmlIterator<>(reader, unmarshaller, "xxxxxx");
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.ORDERED), false);
} catch (XMLStreamException e1) {
logger.error("XMLStreamException", e1);
} catch (JAXBException e) {
logger.error("JAXBException", e);
}
和
public class XmlIterator<T> implements Iterator<T> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
XMLEventReader reader;
XMLEvent event;
Unmarshaller unmarshaller;
String name;
public XmlIterator(XMLEventReader reader, Unmarshaller unmarshaller, String name) {
this.reader = reader;
this.unmarshaller = unmarshaller;
this.name = name;
try {
reader.next();
this.event = reader.peek();
} catch (XMLStreamException e) {
logger.error("", e);
event = null;
}
}
@Override
public boolean hasNext() {
try {
while (event != null && !(event.isStartElement() && name.equals(event.asStartElement().getName().getLocalPart()))) {
Object a = reader.next();
event = reader.peek();
}
return event != null;
} catch (XMLStreamException e) {
logger.error("", e);
event = null;
}
return event != null;
}
@Override
public T next() {
try {
T next = ((JAXBElement<T>) unmarshaller.unmarshal(reader)).getValue();
event = reader.peek();
return next;
} catch (JAXBException e) {
logger.error("error during unmarshalling ", e);
return null;
} catch (XMLStreamException e) {
logger.error("error during stream ", e);
return null;
}
}
}
您是否知道使用不同的技術和API讀取Java中的XML文件?你認爲哪一個適合這裏? XML文件將會有多大?可能你想看看[StAX](https://docs.oracle.com/javase/tutorial/jaxp/stax/api.html),但是你可以在你的問題中添加更多的上下文嗎? – Tunaki
是的,我知道很多lib,但它們都非常低級。我不明白爲什麼在2016年我仍然必須分析手動啓動start_element以生成自己的流,只要我可以指定Xpath。 – sab
「我仍然需要手動分析start_element以生成自己的流」:看看jaxb(=爲數據定義一個xml架構) – Pierre