问题描述
我想使用 JAXB 将 XML 文件解组为 java 对象.XML 文件非常大,包含一些节点,在某些情况下我想跳过这些节点以提高性能,因为客户端 java 程序无法编辑这些元素.
I want to unmarshal an XML file to java object using JAXB. The XML file is very large and contains some nodes which I want to skip in some cases to improve performance as these elements are non editable by client java program.
示例 XML 如下:
<Example id="10" date="1970-01-01" version="1.0">
<Properties>...</Properties>
<Summary>...</Summary>
<RawData>
<Document id="1">...</Document>
<Document id="2">...</Document>
<Document id="3">...</Document>
------
------
</RawData>
<Location></Location>
<Title></Title>
----- // more elements
</Example>
我有两个用例:
- 解组到包含属性、摘要、RawData 等的 Example 对象,而不跳过任何 RawData.(这部分已经做完了)
- 解组为排除 RawData 的 Example 对象.嵌套在 RawData 中的元素非常大,因此不想在此用例中读取它.
现在我想解组 XML,以便可以跳过 RawData.我已经尝试了 此链接提供的技术.
Now I want to unmarshal the XML such that RawData can be skipped. I have tried the technique provided at this link.
使用上面链接中提供的技术也会跳过 RawData 之后的所有元素.
Using technique provided in above link also skips all elements which come after RawData.
推荐答案
我已经使用以下代码修复了 XMLEventReader 的问题:
I have fixed the issue with XMLEventReader with following code:
public class PartialXmlEventReader implements XMLEventReader {
private final XMLEventReader reader;
private final QName qName;
private boolean skip = false;
public PartialXmlEventReader(final XMLEventReader reader, final QName element) {
this.reader = reader;
this.qName = element;
}
@Override
public String getElementText() throws XMLStreamException {
return reader.getElementText();
}
@Override
public Object getProperty(final String name) throws IllegalArgumentException {
return reader.getProperty(name);
}
@Override
public boolean hasNext() {
return reader.hasNext();
}
@Override
public XMLEvent nextEvent() throws XMLStreamException {
while (isEof(reader.peek())) {
reader.nextEvent();
}
return reader.nextEvent();
}
@Override
public XMLEvent nextTag() throws XMLStreamException {
return reader.nextTag();
}
@Override
public XMLEvent peek() throws XMLStreamException {
return reader.peek();
}
@Override
public Object next() {
return reader.next();
}
@Override
public void remove() {
reader.remove();
}
@Override
public void close() throws XMLStreamException {
reader.close();
}
private boolean isEof(final XMLEvent e) {
boolean returnValue = skip;
switch (e.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
final StartElement se = (StartElement) e;
if (se.getName().equals(qName)) {
skip = true;
returnValue = true;
}
break;
case XMLStreamConstants.END_ELEMENT:
final EndElement ee = (EndElement) e;
if (ee.getName().equals(qName)) {
skip = false;
}
break;
}
return returnValue;
}
}
虽然解组只是将这个 eventReader 传递给解组方法
While Unmarshalling just pass this eventReader to the unmarshal method
final JAXBContext context = JAXBContext.newInstance(classes);
final Unmarshaller um = context.createUnmarshaller();
Reader reader = null;
try {
reader = new BufferedReader(new FileReader(xmlFile));
final QName qName = new QName("RawData");
final XMLInputFactory xif = XMLInputFactory.newInstance();
final XMLEventReader xmlEventReader = xif.createXMLEventReader(reader);
final Example example =
(Example) um.unmarshal(new PartialXmlEventReader(xmlEventReader, qName));
}
} finally {
IOUtils.closeQuietly(reader);
}
这篇关于使用 JAXB 对 XML 进行部分解组以跳过某些 xmlElement的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!