我想使用JAXB将XML文件解组为java对象. XML文件非常大,包含一些我想在某些情况下跳过的节点,以提高性能,因为客户端java程序无法编辑这些元素.
示例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>
我有两个用例:
> unmarshal into Example对象,其中包含Properties,Summaries,RawData等,而不跳过任何RawData. (已完成此部分)
> unmarshal into Example对象,不包括RawData.嵌套在RawData中的元素非常大,因此不希望在此用例中阅读此内容.
现在我想解组XML,以便可以跳过RawData.我尝试过this link提供的技术.
使用上面链接中提供的技术也会跳过RawData之后的所有元素.
我已使用以下代码修复了XMLEventReader的问题:
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; }
}
虽然Unmarshalling只是将这个eventReader传递给unmarshal方法
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); }