在Java7和Java8中,对缩进的XML进行解组会得到不同的结果

在Java7和Java8中,对缩进的XML进行解组会得到不同的结果,java,xml,jaxb,Java,Xml,Jaxb,切换到Java8使我的一个测试失败。以下是一个简明示例: public static class Wrapper { @XmlMixed @XmlAnyElement(lax = true) public List<Object> content; } public static void main(String[] args) throws XMLStreamException, JAXBException { final String xml =

切换到Java8使我的一个测试失败。以下是一个简明示例:

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 8(1.8.0_45):
String
ElementNSImpl
String

[[b: null], 
]
[
  , [b: null], 
]
在本例中,Java7似乎忽略了前导空格,而Java8则没有。我的问题是:

  • 这种不同行为的根本原因是什么
  • 如何使Java8表现为Java7?或者至少在两个Java版本中具有一致的行为

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

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

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

这样,无论其他库将哪些JAR文件添加到类路径/类加载器中,您都可以绝对保证使用您认为自己是的解析器。

听起来很合理。两个解析器能否在同一个应用程序中安全共存?我正在考虑在这里使用一个特定的实现,并将用于XML解析的其他代码保留为默认的。@stholzm两个解析器可以安全地共存,尽管一旦Woodstox位于类路径上,它通常将由
XMLInputFactory.newFactory()
使用,而不是内置在rt.jar中的解析器。问题是如果其他库引入了另一个解析器(sjsxp),那么您无法确定哪一个会赢。使用
new WstxInputFactory()
将删除反射查找,以便了解得到的结果。