JAXB2类型限制不起作用?

时间:2014-10-28 21:17:21

标签: java jaxb unmarshalling jaxb2

我在github上设置了一个测试单元。有人可以检查为什么这不起作用虽然XML解组看起来不错?

https://github.com/jjYBdx4IL/misc-tests/blob/master/src/test/java/jjybdx4il/jaxb/bugs/Stackoverflow26618647Test.java

"<?xml version=\"1.0\" encoding=\"UTF-8\"?><message:GenericData xmlns:message=\"http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message\" xmlns:common=\"http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:generic=\"http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic\" xsi:schemaLocation=\"http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message https://sdw-wsrest.ecb.europa.eu/vocabulary/sdmx/2_1/SDMXMessage.xsd http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common https://sdw-wsrest.ecb.europa.eu/vocabulary/sdmx/2_1/SDMXCommon.xsd http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic https://sdw-wsrest.ecb.europa.eu/vocabulary/sdmx/2_1/SDMXDataGeneric.xsd\">\n"
            + "<message:Header>\n" ...

最外层元素GenericDataType被正确实例化。我使用调试器检查了这一点并将断点设置为手工制作的公共构造函数。但是,消息:Header元素导致BaseHeaderType类的实例化,这是抽象的。

在SDMXMessage.xsd中,明确指出GenericDataType的标头仅限于GenericDataHeaderType:

<xs:complexType name="GenericDataType">
    <xs:annotation>
        <xs:documentation>GenericDataType defines the contents of a generic data message.</xs:documentation>
    </xs:annotation>
    <xs:complexContent>
        <xs:restriction base="MessageType">
            <xs:sequence>
                <xs:element name="Header" type="GenericDataHeaderType"/>
                <xs:element name="DataSet" type="data:DataSetType" minOccurs="0" maxOccurs="unbounded"/>
                <xs:element ref="footer:Footer" minOccurs="0"/>
            </xs:sequence>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

为什么xjc会在代码生成期间忽略它?

public abstract class MessageType {

@XmlElement(name = "Header", required = true)
protected BaseHeaderType header;
@XmlAnyElement(lax = true)
protected List<Object> any;
@XmlElement(name = "Footer", namespace = "http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message/footer")
protected FooterType footer;

public class GenericDataType
    extends MessageType {
}

我能做些什么吗?从XSD文件创建实际工作的Java域模型的任何自动替代方法?

1 个答案:

答案 0 :(得分:1)

好的,我会将此作为答案发布。

由于这种类型的构造,您遇到了这个问题:

<xs:complexType name="MessageType" abstract="true">
    <xs:annotation>
        <xs:documentation>MessageType is an abstract type which is used by all of the messages, to allow inheritance of common features. Every message consists of a mandatory header, followed by optional payload (which may occur multiple times), and finally an optional footer section for conveying error, warning, and informational messages.</xs:documentation>
    </xs:annotation>
    <xs:sequence>
        <xs:element name="Header" type="BaseHeaderType"/>
        <xs:any namespace="##targetNamespace" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="footer:Footer" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>   

...

<xs:complexType name="GenericDataType">
    <xs:annotation>
        <xs:documentation>GenericDataType defines the contents of a generic data message.</xs:documentation>
    </xs:annotation>
    <xs:complexContent>
        <xs:restriction base="MessageType">
            <xs:sequence>
                <xs:element name="Header" type="GenericDataHeaderType"/>
                <xs:element name="DataSet" type="data:DataSetType" minOccurs="0" maxOccurs="unbounded"/>
                <xs:element ref="footer:Footer" minOccurs="0"/>
            </xs:sequence>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

一个元素仅限于更具体的元素/类型(DataSet)。由于所有属性都已在super classe上定义,因此XJC不会在“继承类”上生成它们

据我所知,存在许多问题reported on restrictions in JAXB RI。通过限制推导似乎是JAXB的一个难题。

例如,在这种情况下 - 您认为GenericDataType应如何?您基本上需要覆盖header属性以使用更具体的类型。由于XJC在字段而不是getter / setter上放置注释,我想知道如何覆盖这样的属性。您可以添加另一个标头属性来处理header,但覆盖?

尝试编写这样的类 - 手动并使用jaxb:class/@ref - 绑定。如果你使它工作,这将给出应该生成什么的想法。

接下来,如果可以通过XJC插件实现。

您在此报告的问题实际上是XJC的核心业务。如果某些东西在那里不起作用,那么“好”的事情就是报告(或找到已报告的问题)并在XJC中解决问题。

XJC插件可以做很多事情。您可以完全重组模型并自定义生成。通过适当的努力,一切皆有可能。

但在这种情况下,这可能是一项冒险的尝试。编写高级XJC插件并不容易。

如果您对插件应该做什么以及如何在模式派生类中修复此特定问题有一个很好的概念,请发表您的想法,也许我们将能够提供一些指导。我个人而言,我可能写的XJC插件比其他任何人都多。

我希望这会有所帮助。