解组缩进的XML在Java 7和8中给出了不同的结果

时间:2015-05-26 17:16:17

标签: java xml jaxb

切换到Java 8使我的一个测试失败。这是一个简洁的例子:

public static class Wrapper {
    @XmlMixed
    @XmlAnyElement(lax = true)
    public List<Object> content;
}

public static void main(String[] args) throws XMLStreamException, JAXBException {
    final String xml = "<a>\n  <b/>\n</a>";
    final XMLInputFactory xif = XMLInputFactory.newFactory();
    final XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xml));

    final JAXBContext context = JAXBContext.newInstance(Wrapper.class);
    final Unmarshaller unmarshaller = context.createUnmarshaller();
    final JAXBElement<Wrapper> element = unmarshaller.unmarshal(xsr, Wrapper.class);

    System.out.println(element.getValue().content);
}

使用Java 7(1.7.0_75)输出:ElementNSImplString

[[b: null], 
]

输出Java 8(1.8.0_45):StringElementNSImplString

[
  , [b: null], 
]

在这种情况下,Java 7似乎忽略了前导空格,而Java 8却没有。我的问题是:

  • 这种不同行为的根本原因是什么?
  • 如何使Java 8像Java 7一样运行?或者至少对两个Java版本都有一致的行为?

PS:@XmlMixed @XmlAnyElement(lax = true)听起来很糟糕,但“包装”类的代码是从SharePoint WSDL生成的。

1 个答案:

答案 0 :(得分:1)

您应该选择特定解析器的特定版本并让您的应用程序依赖于它,而不是使用与Java运行时捆绑在一起的默认StAX解析器(在不同版本中可能表现不同)。您可以简单地在您的应用程序的类路径中包含(例如)Woodstox的JAR,并依赖XMLInputFactory.newFactory()的默认行为来优先于捆绑的行为,但更安全(更高性能) )将直接自己实例化适当的对象。

XMLInputFactory xif = new com.ctc.wstx.stax.WstxInputFactory();

通过这种方式,您可以绝对保证使用您认为自己的解析器,而不管其他任何库将其他JAR文件添加到类路径/类加载器中。