JAXB converts @XmlElementRefs and @XmlElements to xs:choice

Viewed 21314

I have 4 classes. Person class, and abstract ContactInformation with Phone and Address class extending it.

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Person {
    @XmlElement(required = true, nillable = false)
    private String first;
    @XmlElement(required = true, nillable = false)
    private String last;
    @XmlElementWrapper(name = "contacts")
    @XmlElementRefs({
        @XmlElementRef(name = "phone", type = Phone.class, required = true),
        @XmlElementRef(name = "address", type = Address.class, required = true)
    })
    private final List<ContactInfomation> contacts = new ArrayList<>();
}

ContactInformation is used only as container:

public abstract class ContactInfomation { /* empty class */ }

Phone class:

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Phone extends ContactInfomation {
    @XmlElement(required = true, nillable = false)
    private String number;
}

And Address class:

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Address extends ContactInfomation {
    @XmlElement(required = true, nillable = false)
    private String country;
    @XmlElement(required = true, nillable = false)
    private String city;
}

The problem is when I change @XmlElementrefs to @XmlElements in Person class, nothing happens. JAXB maps them to xs:choice. The XML output is same as before and schemagen generates the same schema as before. Here is a sample output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
    <first>majid</first>
    <last>azimi</last>
    <contacts>
        <address>
            <country>US</country>
            <city>Los Angles</city>
        </address>
        <address>
            <country>US</country>
            <city>New York</city>
        </address>
        <phone>
            <number>5551037</number>
        </phone>
    </contacts>
</person>

And here is the schema:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="address" type="address"/>

  <xs:element name="person" type="person"/>

  <xs:element name="phone" type="phone"/>

  <xs:complexType name="person">
    <xs:sequence>
      <xs:element name="first" type="xs:string"/>
      <xs:element name="last" type="xs:string"/>
      <xs:element name="contacts" minOccurs="0">
        <xs:complexType>
          <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
              <xs:element ref="phone"/>
              <xs:element ref="address"/>
            </xs:choice>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="phone">
    <xs:complexContent>
      <xs:extension base="contactInfomation">
        <xs:sequence>
          <xs:element name="number" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="contactInfomation" abstract="true">
    <xs:sequence/>
  </xs:complexType>

  <xs:complexType name="address">
    <xs:complexContent>
      <xs:extension base="contactInfomation">
        <xs:sequence>
          <xs:element name="country" type="xs:string"/>
          <xs:element name="city" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>

Documentation of @XmlElementRef uses it for Substitution group and XML choice. I'm completely confused what is the difference of @XmlElementRefs/@XmlElementRef and @XmlElements/@XmlElement. Can anyone help?

1 Answers
Related