我正在JAXBContext类中试验各种形式的newInstance方法(我使用的是 Oracle JDK 1.7 附带的默认 Sun JAXB 实现)。
我不清楚何时可以将具体类与ObjectFactory类传递给newInstance方法。我应该注意,我使用 JAXB 纯粹是为了解析 XML 文件,即仅在 XML->Java 方向上。
这是证明我的观点的绝对最少的代码:
.xsd 文件
<?xml version="1.0" encoding="UTF-8"?>
<schema elementFormDefault="qualified"
xmlns ="http://www.w3.org/2001/XMLSchema"
xmlns:a ="http://www.example.org/A"
targetNamespace="http://www.example.org/A">
<element name="root" type="a:RootType"></element>
<complexType name="RootType">
<sequence>
<element name="value" type="string"></element>
</sequence>
</complexType>
</schema>
鉴于上述 XSD,以下JAXBInstance.newInstance调用成功地创建了可以解析示例a.xml文件的上下文:
- jc = JAXBContext.newInstance("example.a");
- jc = JAXBContext.newInstance(example.a.ObjectFactory.class);
- jc = JAXBContext.newInstance(example.a.RootType.class, example.a.ObjectFactory.class);
但是,单独传递example.a.RootType.class会在运行时出现javax.xml.bind.UnmarshalException失败:
jc = JAXBContext.newInstance(example.a.RootType.class); // this fails at runtime.
任何人都可以解释一下吗?我在这些JAXBContext::newInstance变体上进行试验的原因是我偶然发现了这个问题,其中接受的答案包括“基于单个类而不是对象工厂构建 JAXB 上下文”的选项。示例a.xml和我正在使用的JAXB Java 代码在文章末尾。
使用的示例 a.xml
<?xml version="1.0" encoding="UTF-8"?>
<a:root xmlns:a="http://www.example.org/A"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/A A.xsd">
<a:value>foo</a:value>
</a:root>
JAXB 解析代码
public static void main (String args[]) throws JAXBException, FileNotFoundException {
JAXBContext jc = null;
message("using package context (press any key:)");
jc = JAXBContext.newInstance("example.a");
work(jc); // SUCCEEDS
message("using Object factory (press any key):");
jc = JAXBContext.newInstance(example.a.ObjectFactory.class);
work(jc); // SUCCEEDS
message("using class enumeration (press any key):");
try {
jc = JAXBContext.newInstance(example.a.RootType.class);
work(jc); // FAILS
} catch (javax.xml.bind.UnmarshalException e) {
e.printStackTrace();
}
message("using class enumeration and Object factory too (press any key):");
jc = JAXBContext.newInstance(example.a.RootType.class, example.a.ObjectFactory.class);
work(jc); // SUCCEEDS
}
private static void work(JAXBContext jc) throws JAXBException, FileNotFoundException {
Unmarshaller u = jc.createUnmarshaller();
RootType root = ((JAXBElement<RootType>)u.unmarshal( new FileInputStream( "a.xml" ))).getValue();
System.out.println( root.getValue() );
}