Search code examples
xmljaxbxsdxml-namespacesjaxb2

JAXB namespace issue with extended annotated class' member


I have 3 annotated classes (I deliberatly removed getters, setters, and so on to make code more readable):

Result.java

@XmlRootElement(name = "resultat")
@XmlType(propOrder = { "state", "content" })
public class Result {
    protected State state;
    protected Content content;
}

Content.java:

@XmlRootElement(name = "content")
@XmlSeeAlso({ Job.class })
public class Content {
}

and Job.java which extends Content:

@XmlType(name = "job", propOrder = { "status" })
@XmlRootElement(name = "job")
public class JobStatus extends Content {
    protected String status;
}

I am setting a Job instance as the value of the content member of the result class, but i get the following generated xml file:

<result>
    <state>
        <tag>value</tag>
    </state>
    <content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="job">
        <status>ok</status>
    </content>
</result>

But it is not a valid xml file and i can not validate it against the following schema because of the "xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="job"" part since job is not a type from http://www.w3.org/2001/XMLSchema-instance.

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="result">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="state">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="tag"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="content">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="status"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

How can i change my JAXB configuration to avoid this problem ?

Thanks !


Solution

  • The problem is not in the JAXB configuration, but in the design of the Schema vs the Java Classes.

    The Java Class Content does not comply with your Schema, since the element status is defined in the Schema but not in the Java Class. Also, you do not define job in your Schema.

    The attribute xsi:type is used for inheritance. Since your JobStatus Class inherits from Content, in XML its displayed as content of type job.

    I think the best solution is to remove the element status from content in your Schema and then define job in your Schema, like so:

    <complexType name="job">
        <complexContent>
            <extension base="content">
                <sequence>
                    <xs:element type="xs:string" name="status"/>
                </sequence>
            </extension>
        </complexContent>
    </complexType>