【问题标题】:How does JAXB advance the XMLStreamReader?JAXB 如何推进 XMLStreamReader?
【发布时间】:2014-07-03 10:41:20
【问题描述】:

我正在使用 JAXB 通过 XMLStreamReader 从非常大的 XML 文件中解组对象。

如果我要解组的 XML 元素是分开的(用换行符甚至是一个空格),这可以正常工作。

如果我要解组的 XML 元素之间没有空格,我会丢失所有其他项目 - XML 阅读器似乎在解组的元素之后吞下了该元素。

https://gist.github.com/dalelane/88df784c3cb74b214d5c 处有一个简化的可运行示例的源代码来证明这一点

有趣的是:

XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
JAXBContext context = JAXBContext.newInstance(MyJAXBClass.class);
Unmarshaller unmarshaller = context.createUnmarshaller();

boolean running = true;
while (running){
    switch (reader.next()){
        case XMLStreamConstants.START_ELEMENT:
            if (reader.getLocalName().equals("myunmarshallobjname")){
                JAXBElement<MyJAXBClass> unmarshalledObj = unmarshaller.unmarshal(reader, MyJAXBClass.class);
                MyJAXBClass item = unmarshalledObj.getValue();
            }
            break;
        case XMLStreamConstants.END_DOCUMENT:
            reader.close();
            running = false;
            break;
    }
}

每次流读取器到达一个元素的开头时,我都会将它传递给解组器以解组该片段。

如果我有以下 XML 文件,它可以工作:

<myunmarshallobjname key="one"></myunmarshallobjname> <myunmarshallobjname key="two"></myunmarshallobjname>

但如果我有物品会丢失:

<myunmarshallobjname key="one"></myunmarshallobjname><myunmarshallobjname key="two"></myunmarshallobjname>

我做错了什么?如何让读者不要跳过元素?

【问题讨论】:

  • 问题出在 JAXB 还是您的代码中?您所说的需要用空格分隔的元素与您在 if 块中匹配的元素相同。
  • 我确定问题出在我的代码中 - 我只是不知道我做错了什么。但是,如果我删除 unmarshall 行,START_ELEMENT 事件会像我期望的那样为每个元素触发。使用 unmarshall,它不会 - 我为每个其他元素得到一个 START_ELEMENT。

标签: java xml jaxb


【解决方案1】:

在 unmarshal 调用之后,仔细检查您正在进行的元素事件。如果 XMLStreamReader 位于 endElement 上,您将需要调用 next() 作为循环的一部分,但它位于 startElement 上,您不会。

【讨论】:

  • 就是这样,谢谢!在我的“工作”案例中解组之后的结束事件是 CHARACTERS - 因为读者指向空白。因此,当我绕过循环并调用 reader.next() 时,它会将我移至下一个元素的开头。在我没有空格的情况下,解组后的结束事件是 START_ELEMENT,因为读者已经指向下一个元素。我绕过循环,调用 reader.next() 并跳过它。
  • 我分享了我的示例的一个固定版本,以防它有助于下一个人尝试这个。 gist.github.com/dalelane/983f278d2485d29a6ef4
  • +1 - 我从来不明白为什么unmarshal(XMLStreamReader) 是这样指定的。当读者在START_ELEMENT 上调用时,我认为它返回时读者指向at 对应的END_ELEMENT 而不是事件after 它。这样您就不需要区分空格和无空格的情况,致电nextTag 总是安全的。
  • @IanRoberts - 我同意你的看法。您描述的行为是我们最初在 EclipseLink JAXB (MOXy) 中所做的,但后来我们对其进行了更改以匹配参考实现,因为这是人们习惯于编码的。
  • 很高兴让内圈的人检查我的理智 :-)
猜你喜欢
  • 1970-01-01
  • 2020-06-19
  • 1970-01-01
  • 2011-07-29
  • 2013-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
相关资源
最近更新 更多