繁体   English   中英

Jaxb implClass规范被rootElement忽略

[英]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.

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