我想使用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);
- }