[英]Jaxb implClass specification ignored for rootElement
我正在尝试为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-tool(但是我也已经使用maven-jaxb2-plugin进行了测试,结果相同)。
为了进行简短测试,我使用了以下XML文档:
<?xml version='1.0' standalone='yes' ?>
<document title="testDocument">
<element title="testElement" />
</document>
当我运行以下测试程序时,顶级文档元素(testDocument)和所包含的子元素(testElement)的结果有所不同。 根的类型为“ DocumentType”,即忽略指定的implClass伪指令,而元素的类型为“ 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,则得到相同的结果。
为什么将implClass忽略为根元素? 任何想法和提示表示赞赏!
扩展以阐明我的意图:
我不想引用现有的,带有jaxb注释的类,但可以使用自动生成的DocumentType-Class作为具有附加属性和方法的引出基类。 为了以后直接编组回XML,我必须保持与XSD-Type的关系。 因此,根据我所知,implClass指令实际上是检测类型类的jaxb生成的适当方法。
它对于内部元素(文档标签内标题为“ testElement”的“ element”)非常有效! 不幸的是,解组器没有使用implClass指定的类正确地实例化根元素。 请参阅上面程序摘录中的结果注释(doc与obj2)。
对于您正在寻找的行为,我相信您想指定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
类,并且ObjectFactory
上的createDocument
方法如下所示:
@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属性互斥。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.