简体   繁体   English

Jaxb implClass规范被rootElement忽略

[英]Jaxb implClass specification ignored for rootElement

I'm trying to specify a implementation class for an XSD-Type. 我正在尝试为XSD-Type指定一个实现类。 Here's a minimal example schema: 这是一个最小的示例架构:

<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>

I'm using the standard xjc-tool from the Java JDK (1.7) for now (but I've also tested with maven-jaxb2-plugin, with the same results). 我现在正在使用Java JDK(1.7)中的标准xjc-tool(但是我也已经使用maven-jaxb2-plugin进行了测试,结果相同)。

For a short test I used the following XML-document: 为了进行简短测试,我使用了以下XML文档:

<?xml version='1.0' standalone='yes' ?>
<document title="testDocument">
  <element title="testElement" />
</document>

When I run the following test program, the results differ for the top-level document element (testDocument) and the contained child element (testElement). 当我运行以下测试程序时,顶级文档元素(testDocument)和所包含的子元素(testElement)的结果有所不同。 The root is of type "DocumentType", ie ignoring the specified implClass-directive, whereas the element is of type "DocumentEx", which is the expected result. 根的类型为“ DocumentType”,即忽略指定的implClass伪指令,而元素的类型为“ DocumentEx”,这是预期的结果。 In the generated ObjectFactory the appropriate instantiation seems correct, but it seems to be not used for the rootElement: 在生成的ObjectFactory中,适当的实例化似乎是正确的,但似乎未用于rootElement:

  public DocumentType createDocumentType() {
    return new DocumentEx();
  }

Here is the test program: 这是测试程序:

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"

I get the same result, if I specify the implClass for the element instead of for the complexType. 如果为元素而不是complexType指定implClass,则得到相同的结果。

Why is the implClass ignored for the root-element? 为什么将implClass忽略为根元素? Any ideas and hints are appreciated! 任何想法和提示表示赞赏!


Extension to clarify my intention: 扩展以阐明我的意图:

I don't want to reference an existing, jaxb-annotated class, but use the auto-generated DocumentType-Class as base class for extionsion with additional attributes and methods. 我不想引用现有的,带有jaxb注释的类,但可以使用自动生成的DocumentType-Class作为具有附加属性和方法的引出基类。 For a later direct marshalling back to XML, I have to keep the relation to the XSD-Type. 为了以后直接编组回XML,我必须保持与XSD-Type的关系。 Therefore the implClass-directive actually is the appropriate (as far as I know) way to instrument the jaxb-generation of the type-classes. 因此,根据我所知,implClass指令实际上是检测类型类的jaxb生成的适当方法。

And it's working perfectly for the inner elements (the 'element' with title 'testElement' inside the document-tag)!! 它对于内部元素(文档标签内标题为“ testElement”的“ element”)非常有效! Unfortunately the unmarshaller does NOT use the implClass-specified class for instantiating the root-element correctly. 不幸的是,解组器没有使用implClass指定的类正确地实例化根元素。 See the result-comments in the program excerpt above (doc vs. obj2). 请参阅上面程序摘录中的结果注释(doc与obj2)。

For the behaviour you are looking for I believe you want to specify ref and not impl : 对于您正在寻找的行为,我相信您想指定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>

This tells JAXB to use the rd.DocumentEx class for the DocumentType complex type. 这告诉JAXB将rd.DocumentEx类用于DocumentType复杂类型。 Now a DocumentType class is not created, and the createDocument method on the ObjectFactory looks like this: 现在,未创建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);
}

From section 7.7.1 of the JAXB 2.2 specification: 从JAXB 2.2规范的7.7.1节开始:

• implClass if specified, is the name of the implementation class for className and must include the complete package name. •implClass(如果已指定)是className的实现类的名称,并且必须包含完整的程序包名称。 Note that this customization only impacts the return value for className's factory method. 请注意,此自定义仅影响className的工厂方法的返回值。 This customization is ignored when new is used to create instances of a schema-derived Value class. 当使用new创建基于架构的Value类的实例时,将忽略此自定义。

• ref if specified, is the name of the value class that is provided outside the schema compiler. •ref(如果已指定)是在模式编译器之外提供的值类的名称。 This customization causes a schema compiler to refer to this external class, as opposed to generate a definition. 这种定制使模式编译器引用此外部类,而不是生成定义。 It must include the complete package name. 它必须包含完整的软件包名称。 This attribute is mutually exclusive with the className attribute and the implClass attribute. 该属性与className属性和implClass属性互斥。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM