如何将名称空间设置为false?

我正在尝试使用EclipseLink MOXy解析一些XML,并且它在使用xsi属性时失败了。 如果我删除它,它解析很好。 但是,我已经获得了100GiB的XML,并且不能更改源文件。

有人建议,如果我可以设置XmlParser.setNamespaceAware(false)那么它应该可以工作 – 但是我不知道如何配置它,而没有直接进入MOXy的内部。

  
info:doi/10.1007/s10973-004-0435-2 2009-04-28 J J:1007 J:1007:2777
[...]

xsi:前缀出现时我得到的例外是:

 org.springframework.oxm.UnmarshallingFailureException: JAXB unmarshalling exception; nested exception is javax.xml.bind.UnmarshalException - with linked exception: [Exception [EclipseLink-25004] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.XMLMarshalException Exception Description: An error occurred unmarshalling the document Internal Exception: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[13,107] Message: http://www.w3.org/TR/1999/REC-xml-names-19990114#AttributePrefixUnbound?crossref&xsi:schemaLocation&xsi] 

EclipseLink JAXB(MOXy)中目前没有一个选项可以告诉它忽略名称空间。 但是有一种方法可以通过利用StAX解析器来使用。

演示

您可以在XML输入上创建一个不支持名称空间的StAX XMLStreamReader ,然后让MOXy解组。

 package forum13416681; import javax.xml.bind.*; import javax.xml.stream.*; import javax.xml.transform.stream.StreamSource; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Foo.class); XMLInputFactory xif = XMLInputFactory.newFactory(); xif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false); StreamSource source = new StreamSource("src/forum13416681/input.xml"); XMLStreamReader xsr = xif.createXMLStreamReader(source); Unmarshaller unmarshaller = jc.createUnmarshaller(); Foo root = (Foo) unmarshaller.unmarshal(xsr); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(root, System.out); } } 

Java模型(Foo)

 package forum13416681; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Foo { private String bar; public String getBar() { return bar; } public void setBar(String bar) { this.bar = bar; } } 

输入(input.xml)

以下是您问题中XML的简化版本。 请注意,此XML未正确命名空间限定,因为它缺少xsi前缀的名称空间声明。

   Hello World  

产量

以下是运行演示代码的输出。

   Hello World  

您可以使用特定于StAX实现的机制来提前声明xsi前缀,然后解析启用的命名空间,而不是完全禁用命名空间感知。 例如,使用Woodstox,您可以说:

 import javax.xml.bind.*; import javax.xml.stream.*; import javax.xml.transform.stream.StreamSource; import com.ctc.wstx.sr.BasicStreamReader; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance("com.example"); XMLInputFactory xif = XMLInputFactory.newFactory(); StreamSource source = new StreamSource("input.xml"); XMLStreamReader xsr = xif.createXMLStreamReader(source); ((BasicStreamReader)xsr).getInputElementStack().addNsBinding( "xsi", "http://www.w3.org/2001/XMLSchema-instance"); 

然后在Blaise的答案中创建unmarshaller并解组xsr 。 虽然这显然将您绑定到一个特定的StAX实现,但这意味着如果他们希望元素及其子元素位于http://www.crossref.org/xschema/1.0 ,则不必修改现有的JAXB模型类http://www.crossref.org/xschema/1.0命名空间。