ekeren
ekeren

Reputation: 3458

when unmarshaling from a schema the order of a sequence matters in jaxb

I have this schema:

<xs:complexType name="foo">
  <xs:sequence>
    <xs:element name="oneBar" type="xs:string" minOccurs="0"/>
    <xs:element name="twoBar" type="xs:string" minOccurs="0"/>
  </xs:sequence>
</xs:complexType>

When I try to unmarshal this

<foo>
  <oneBar>1</oneBar>
  <twoBar>2</twoBar>
</foo>

it works but when I try to unmarshal this xml:

<foo>
   <twoBar>2</twoBar>
   <oneBar>1</oneBar>
</foo>

I get an excelption because it cares about the order If I try to unmarshal the same xml without using a schema it works in both cases Any ideas?

As Strawberry pointed out if you replace the xs:sequence with sc:any order wont matter, does any of you know what annotation I need to put in my class so it will generate the xs:any schmea

Found solution by creating the class from the xs:any schema You just need to annotate your class with XmlType and set the prop order to be nothing, see:

@XmlRootElement
@XmlType(name="foo",propOrder={})
public class Foo {
    @XmlElement
    public String oneBar; 
    @XmlElement
    public String twoBar;
} 

Upvotes: 2

Views: 2633

Answers (1)

Martin
Martin

Reputation: 7139

Sequence requires elements be in order e.g. from w3schools page:-

The indicator specifies that the child elements must appear in a specific order:

When unmarshalling without a schema you are effectively not validating the XML.

If you want your schema to NOT require a specific ordering then the following should do that:-

<xs:complexType name="foo">
  <xs:all>
    <xs:element name="oneBar" type="xs:string" minOccurs="0"/>
    <xs:element name="twoBar" type="xs:string" minOccurs="0"/>
  </xs:all>
</xs:complexType>

Approaching it from the Java annotation point of view. If I have a Class called Test with two string fields test1 and test2, the annotations would be:-

The ordered case e.g. using <sequence>

@XmlType(name="",propOrder={"test1","test2"})
@XmlRootElement(name="test")
public class Test
{
   @XmlElement(required=true)
   private String test1;
   @XmlElement(required=true)
   private String test2;
}

The un-ordered case e.g. using <all>

@XmlType(name="",propOrder={})
@XmlRootElement(name="test")
public class Test
{
   @XmlElement(required=true)
   private String test1;
   @XmlElement(required=true)
   private String test2;
}

Upvotes: 6

Related Questions