使用 JAXB 对 XML 进行部分解组以跳过一些 xmlElement [英] Partial Unmarshalling of an XML using JAXB to skip some xmlElement

查看:43
本文介绍了使用 JAXB 对 XML 进行部分解组以跳过一些 xmlElement的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 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 如下:

A sample XML is as follows:

<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 的示例对象.嵌套在 RawData 中的元素非常大,因此不想在此用例中阅读此内容.

现在我想解组 XML 以便可以跳过 RawData.我已经尝试过 this link 提供的技术.

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;
}

}

Unmarshalling 时只需将此 eventReader 传递给 unmarshal 方法

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆