Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB not creating member variables and getters and setters

Tags:

java

xml

jaxb

xsd

I am trying to generate Java classes form xsd schema and I am using JAXB. For the most part when I run the process to generate the classes it works. However there are a few classes that the member variable, getters , and setters are not generated. Here is what I have

File ns2.xsd

<xs:element name="Observation" type="ns2:ObservationType" substitutionGroup="ns1:_MetaData"/>
<xs:complexType name="ObservationType" mixed="true">
    <xs:complexContent mixed="true">
        <xs:extension base="ns1:AbstractType">
            <xs:sequence>
                    <xs:element ref="ns2:identifier"/>

            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

File ns3.xsd

<xs:element name="Observation" type="ns3:ObservationType" substitutionGroup="ns2:Observation"/>
<xs:complexType name="ObservationType" mixed="true">
    <xs:annotation>
        <xs:documentation>this extends the ns2:ObservationType </xs:documentation>
    </xs:annotation>
    <xs:complexContent mixed="true">
        <xs:extension base="ns2:ObservationType">
            <xs:sequence>
                <xs:element ref="ns3:deliveryInfo" minOccurs="0"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

This creates an empty class

package mypackage.ns3;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;


/**
 * this extends the ns2:ObservationType 
 * 
 * <p>Java class for ObservationType complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="ObservationType">
 *   &lt;complexContent>
 *     &lt;extension base="{http://earth.esa.int/ns2}ObservationType">
 *       &lt;sequence>
 *         &lt;element ref="{http://earth.esa.int/ns3}deliveryInfo" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/extension>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ObservationType")
public class ObservationType
    extends mypackage.ns2.ObservationType
{


}

My question is why is not creating the required member variable and its setters and getters? Is there something wrong with the schema or is there a limitation on JAXB to create the missing information form complex types that use extensions from different files? Thank you in advance. Your help or comments will be appreciated.

like image 851
user2639371 Avatar asked Nov 02 '22 17:11

user2639371


1 Answers

What makes this use case odd is that you have inheritance in your XML Schema between two types with mixed content. I think there is an XJC (and possibly spec) bug here, and as suggested by Puce you should enter a bug for it at the following link:

  • https://java.net/jira/browse/JAXB/

XML Schema

schema.xsd

Here is a simpler XML schema that reproduces the same issue:

<?xml version="1.0" encoding="UTF-8"?>
<schema 
    xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/schema" 
    xmlns:tns="http://www.example.org/schema" 
    elementFormDefault="qualified">

    <complexType name="b" mixed="true">
                 <sequence>
                   <element ref="tns:bb"/>
                </sequence>
    </complexType>


    <complexType name="c">
        <complexContent mixed="true">
            <extension base="tns:b">
                <sequence>
                   <element ref="tns:cc"/>
                </sequence>
            </extension>
        </complexContent>
    </complexType>

    <element name="bb" type="string"/>

    <element name="cc" type="string"/>

</schema>

Incorrect Java Model

B

The class generated for the b type is fine.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "b", propOrder = {"content"})
@XmlSeeAlso({C.class})
public class B {

    @XmlElementRef(name = "bb", namespace = "http://www.example.org/schema", type = JAXBElement.class)
    @XmlMixed
    protected List<Serializable> content;

    public List<Serializable> getContent() {
        if (content == null) {
            content = new ArrayList<Serializable>();
        }
        return this.content;
    }

}

C

The class generated for the c type is wrong, the question is what should it be?

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "c")
public class C extends B {


}

Better Java Model? - Option #1

You could add a property to the C class. The question then comes down to which of the mixed text goes on the property inherited from B and which goes in the property defined on C.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "c")
public class C
    extends B
{

    @XmlElementRef(name = "cc", namespace = "http://www.example.org/schema", type = JAXBElement.class)
    @XmlMixed
    protected List<Serializable> content2;

}

Better Java Model? - Option #2

You could extend the property on B to be aware of the element reference from the c type. This will allow you to handle the XML correctly for the b and c types but would allows some documents that weren't valid against the XML schema.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "b", propOrder = {"content"})
@XmlSeeAlso({C.class})
public class B {

    @XmlElementRefs({
        @XmlElementRef(name = "bb", namespace = "http://www.example.org/schema", type = JAXBElement.class),
        @XmlElementRef(name = "cc", namespace = "http://www.example.org/schema", type = JAXBElement.class)
    })
    @XmlMixed
    protected List<Serializable> content;

    public List<Serializable> getContent() {
        if (content == null) {
            content = new ArrayList<Serializable>();
        }
        return this.content;
    }

}
like image 59
bdoughan Avatar answered Nov 09 '22 12:11

bdoughan