我正在尝试为XSD-Type指定一个实现类。 这是一个最小的示例模式:
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="rd.test"
xmlns:tns="rd.test" elementFormDefault="qualified"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0">
<complexType name="DocumentType">
<annotation>
<appinfo>
<jaxb:class implClass="rd.DocumentEx" />
</appinfo>
</annotation>
<sequence>
<element name="element" type="tns:DocumentType" />
</sequence>
<attribute name="title" type="string" />
</complexType>
<element name="document" type="tns:DocumentType"/>
</schema>
我现在正在使用Java JDK(1.7)中的标准xjc工具(但我也测试了maven-jaxb2-plugin,结果相同)。
对于简短测试,我使用了以下XML文档:
<?xml version='1.0' standalone='yes' ?>
<document title="testDocument">
<element title="testElement" />
</document>
当我运行以下测试程序时,顶级文档元素(testDocument)和包含的子元素(testElement)的结果不同。根类型为“DocumentType”,即忽略指定的implClass-directive,而该元素的类型为“DocumentEx”,这是预期的结果。 在生成的ObjectFactory中,相应的实例化似乎是正确的,但似乎没有用于rootElement:
public DocumentType createDocumentType() {
return new DocumentEx();
}
以下是测试程序:
InputStream inp=new FileInputStream(new File("test.xml"));
JAXBContext jaxbContext = JAXBContext.newInstance("test.rd");
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement el = (JAXBElement)unmarshaller.unmarshal(inp);
Object obj = el.getValue();
System.out.println("doc: " + obj);
// result: "doc: test.rd.DocumentType@d1c5bb0"
DocumentType doc = (DocumentType)obj;
Object obj2=doc.getElement();
System.out.println("obj2: " + obj2);
// result: "obj2: rd.DocumentEx@d1c5bb0"
如果我为元素而不是complexType指定implClass,我会得到相同的结果。
为什么root元素会忽略implClass? 任何想法和提示都表示赞赏!
扩展以澄清我的意图:
我不想引用现有的带有jaxb注释的类,但是使用自动生成的DocumentType-Class作为extionsion的基类以及其他属性和方法。为了以后直接编组回XML,我必须保持与XSD-Type的关系。因此,implClass指令实际上是适当的(据我所知)方法来检测类型类的jaxb生成。
它完美适用于内部元素(文档标记内标题为'testElement'的'元素')!!不幸的是,unmarshaller不会使用implClass指定的类来正确地实例化根元素。请参阅上面的程序摘录中的结果 - 注释(doc vs. obj2)。
答案 0 :(得分:0)
对于您要查找的行为,我认为您要指定ref
而不是impl
:
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="rd.test"
xmlns:tns="rd.test" elementFormDefault="qualified"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0">
<complexType name="DocumentType">
<annotation>
<appinfo>
<jaxb:class ref="rd.DocumentEx" />
</appinfo>
</annotation>
<sequence>
<element name="element" type="tns:DocumentType" />
</sequence>
<attribute name="title" type="string" />
</complexType>
<element name="document" type="tns:DocumentType"/>
</schema>
这告诉JAXB将rd.DocumentEx
类用于DocumentType
复杂类型。现在没有创建DocumentType
类,createDocument
上的ObjectFactory
方法如下所示:
@XmlElementDecl(namespace = "rd.test", name = "document")
public JAXBElement<DocumentEx> createDocument(DocumentEx value) {
return new JAXBElement<DocumentEx>(_Document_QNAME, DocumentEx.class, null, value);
}
来自JAXB 2.2规范的第7.7.1节:
•如果指定implClass,则为实现类的名称 className并且必须包含完整的包名称。请注意这一点 自定义仅影响className工厂的返回值 方法。使用new创建时,将忽略此自定义 模式派生的Value类的实例。
•ref如果指定,则为 在架构编译器外部提供的值类的名称。 此自定义导致架构编译器引用此外部 类,而不是生成定义。它必须包括 完整的包名。该属性与。互斥 className属性和implClass属性。