【发布时间】:2016-09-21 00:05:47
【问题描述】:
有这样一个供应商提供的 XML:
<?xml version="1.0" encoding="utf-8"?>
<Foo>
<Bar>...</Bar>
<Bar>...</Bar>
</Foo>
请注意,没有xmlns="..." 声明,供应商也没有提供架构。这是无法更改的,供应商将在未来继续以这种方式发布 XML。
为了生成 JAXB 绑定,我创建了这样的模式:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://acme.com/schema"
xmlns:tns="http://acme.com/schema"
elementFormDefault="qualified">
<xsd:element name="Foo">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="tns:Bar" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Bar">
...
</xsd:element>
</xsd:schema>
请注意,我已经声明了一个或多或少有意义的命名空间(“http://acme.com/schema”),以便它可以用于元素引用等。XJC 生成以下package-info.java:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://acme.com/schema", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.acme.schema;
然后我尝试解组 XML 文档:
JAXBContext jaxb = JAXBContext.newInstance("com.acme.schema");
Unmarshaller unmarshaller = jaxb.createUnmarshaller();
InputStream is = this.getClass().getClassLoader().getResourceAsStream("test.xml");
InputSource source = new InputSource(is);
Foo foo = (Foo) unmarshaller.unmarshal(source);
这是我得到的例外:
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"Foo"). Expected elements are <{http://acme.com/schema}Foo>,...>
显然,这是因为 XML 元素属于一个空命名空间,而 JAXB 类有一个非空命名空间。
有没有办法伪造一个 XML 命名空间(可能在 XML 解析期间),以便 JAXB 能够识别元素并成功绑定它们? SAX/StAX 解决方案将优于 DOM,因为 XML 文档可能相当庞大。
【问题讨论】:
-
你介意把 XJC 生成的类放在上面吗?