title: JAXB: Represent nested Model Group Schema Components with a java object hierarchy
body: <p>Schema allows a designer to specify optional sequences of child elements as follows;</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/Schema1" xmlns:tns="http://www.example.org/Schema1" elementFormDefault="qualified"&gt;
  
      &lt;complexType name="RootType"&gt;
          &lt;sequence&gt;
              &lt;choice&gt;
                  &lt;sequence minOccurs="1" maxOccurs="1"&gt;
                      &lt;element name="A" type="tns:A"&gt;&lt;/element&gt;
                      &lt;element name="B" type="tns:B"&gt;&lt;/element&gt;
                      &lt;element name="C" type="tns:C"&gt;&lt;/element&gt;
                  &lt;/sequence&gt;
                  &lt;element name="P" type="tns:P" minOccurs="1" maxOccurs="1"&gt;&lt;/element&gt;
                  &lt;element name="Q" type="tns:Q" minOccurs="1" maxOccurs="1"&gt;&lt;/element&gt;
              &lt;/choice&gt;
          &lt;/sequence&gt;
      &lt;/complexType&gt;
  
      &lt;complexType name="A"&gt;
          &lt;sequence&gt;
              &lt;element name="one" type="string"/&gt;
              &lt;element name="two" type="string"/&gt;
              &lt;element name="three" type="string"/&gt;
          &lt;/sequence&gt;
      &lt;/complexType&gt;
  
      &lt;complexType name="B"&gt;
          &lt;sequence&gt;
              &lt;element name="one" type="string"/&gt;
              &lt;element name="two" type="string"/&gt;
              &lt;element name="three" type="string"/&gt;
          &lt;/sequence&gt;
      &lt;/complexType&gt;
  
      &lt;complexType name="C"&gt;
          &lt;sequence&gt;
              &lt;element name="one" type="string"/&gt;
              &lt;element name="two" type="string"/&gt;
              &lt;element name="three" type="string"/&gt;
          &lt;/sequence&gt;
      &lt;/complexType&gt;
  
      &lt;complexType name="P"&gt;
          &lt;sequence&gt;
              &lt;element name="one" type="string"/&gt;
              &lt;element name="two" type="string"/&gt;
              &lt;element name="three" type="string"/&gt;
          &lt;/sequence&gt;
      &lt;/complexType&gt;
  
      &lt;complexType name="Q"&gt;
          &lt;sequence&gt;
              &lt;element name="one" type="string"/&gt;
              &lt;element name="two" type="string"/&gt;
              &lt;element name="three" type="string"/&gt;
          &lt;/sequence&gt;
      &lt;/complexType&gt;
  
      &lt;element name="TopLevel" type="tns:RootType"&gt;&lt;/element&gt;
  &lt;/schema&gt;
  </code></pre>
  
  <p>This validates</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;tns:TopLevel xmlns:tns="http://www.example.org/Schema1"&gt;
      &lt;tns:A&gt;
          &lt;tns:one&gt;tns:one&lt;/tns:one&gt;
          &lt;tns:two&gt;tns:two&lt;/tns:two&gt;
          &lt;tns:three&gt;tns:three&lt;/tns:three&gt;
      &lt;/tns:A&gt;
      &lt;tns:B&gt;
          &lt;tns:one&gt;tns:one&lt;/tns:one&gt;
          &lt;tns:two&gt;tns:two&lt;/tns:two&gt;
          &lt;tns:three&gt;tns:three&lt;/tns:three&gt;
      &lt;/tns:B&gt;
      &lt;tns:C&gt;
          &lt;tns:one&gt;tns:one&lt;/tns:one&gt;
          &lt;tns:two&gt;tns:two&lt;/tns:two&gt;
          &lt;tns:three&gt;tns:three&lt;/tns:three&gt;
      &lt;/tns:C&gt;
  &lt;/tns:TopLevel&gt;
  </code></pre>
  
  <p>and rejects</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;tns:TopLevel xmlns:tns="http://www.example.org/Schema1"&gt;
      &lt;tns:A&gt;
          &lt;tns:one&gt;tns:one&lt;/tns:one&gt;
          &lt;tns:two&gt;tns:two&lt;/tns:two&gt;
          &lt;tns:three&gt;tns:three&lt;/tns:three&gt;
      &lt;/tns:A&gt;
      &lt;tns:B&gt;
          &lt;tns:one&gt;tns:one&lt;/tns:one&gt;
          &lt;tns:two&gt;tns:two&lt;/tns:two&gt;
          &lt;tns:three&gt;tns:three&lt;/tns:three&gt;
      &lt;/tns:B&gt;
  &lt;/tns:TopLevel&gt;
  </code></pre>
  
  <p>or </p>
  
  <pre><code>   &lt;?xml version="1.0" encoding="UTF-8"?&gt;
      &lt;tns:TopLevel xmlns:tns="http://www.example.org/Schema1"&gt;
          &lt;tns:A&gt;
              &lt;tns:one&gt;tns:one&lt;/tns:one&gt;
              &lt;tns:two&gt;tns:two&lt;/tns:two&gt;
              &lt;tns:three&gt;tns:three&lt;/tns:three&gt;
          &lt;/tns:A&gt;
          &lt;tns:B&gt;
              &lt;tns:one&gt;tns:one&lt;/tns:one&gt;
              &lt;tns:two&gt;tns:two&lt;/tns:two&gt;
              &lt;tns:three&gt;tns:three&lt;/tns:three&gt;
          &lt;/tns:B&gt;
          &lt;tns:C&gt;
              &lt;tns:one&gt;tns:one&lt;/tns:one&gt;
              &lt;tns:two&gt;tns:two&lt;/tns:two&gt;
              &lt;tns:three&gt;tns:three&lt;/tns:three&gt;
          &lt;/tns:C&gt;
          &lt;tns:P&gt;
              &lt;tns:one&gt;tns:one&lt;/tns:one&gt;
              &lt;tns:two&gt;tns:two&lt;/tns:two&gt;
              &lt;tns:three&gt;tns:three&lt;/tns:three&gt;
          &lt;/tns:P&gt;
      &lt;/tns:TopLevel&gt;
  </code></pre>
  
  <p>Ofcourse if I generate a JAXB class from this I get</p>
  
  <pre><code>...
  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(name = "RootType", propOrder = {
      "a",
      "b",
      "c",
      "p",
      "q"
  })
  //Manually added for testing 
  @XmlRootElement(name="TopLevel")
  public class RootType {
  
      @XmlElement(name = "A")
      protected A a;
      @XmlElement(name = "B")
      protected B b;
      @XmlElement(name = "C")
      protected C c;
      @XmlElement(name = "P")
      protected P p;
      @XmlElement(name = "Q")
      protected Q q;
  
      /**
       * Gets the value of the a property.
       * 
       * @return
       *     possible object is
       *     {@link A }
       *     
       */
      public A getA() {
          return a;
      }
  
      /**
       * Sets the value of the a property.
       * 
       * @param value
       *     allowed object is
       *     {@link A }
       *     
       */
      public void setA(A value) {
          this.a = value;
      }
  
      ....
  
      etc.
  </code></pre>
  
  <p>which will load all 3 instances without complaining provided if I don't set up the Schema validation on the Unmarshaller.</p>
  
  <p>The java instance is then contrary to the Schema, and the following will fail. Even if it is valid I must do extra work to determine what state the RootType instance is in.</p>
  
  <pre><code>private static void validate(uk.co.his.test.complexSequenceAndChoice.generated.nact1moxy.RootType root)
  {
      if(root.getA()!=null)
      {
          Assert.assertTrue("RootType should either be a sequence of A, B, C or a sinle P or a single Q", root.getB()!=null&amp;&amp;root.getC()!=null&amp;&amp;root.getP()==null&amp;&amp;root.getQ()==null);
      }
      else
      {
          Assert.assertTrue("RootType should either be a sequence of A, B, C or a sinle P or a single Q", root.getB()==null&amp;&amp;root.getC()==null
                  &amp;&amp;((root.getP()!=null&amp;&amp;root.getQ()==null)
                  || (root.getP()==null&amp;&amp;root.getQ()!=null)));
      }
  }
  </code></pre>
  
  <p>The question is; </p>
  
  <ul>
  <li>Is there anyway to represent this more accurately in a Java class hierachy? 
  Generally <a href="http://www.w3.org/TR/xmlschema-1/#Model_Groups" rel="nofollow">Model Group Schema Components</a>  specify the ordering of child elements, but Java can only capture the 'bucket of all children' in cases where more complex orderings are specified by nested Model Group Schema components?</li>
  </ul>
  
  <p>The difficulty is we would like to represent these groupings by java classes that do not bind to Element parsing events in a one to one way;</p>
  
  <p>Imagine a @XmlElementSequence annotation existed that allowed a sequence of children to be specified;</p>
  
  <pre><code>package uk.co.his.test.complexSequenceAndChoice.manual5;
  
  import javax.xml.bind.annotation.XmlAccessType;
  import javax.xml.bind.annotation.XmlAccessorType;
  import javax.xml.bind.annotation.XmlElement;
  import javax.xml.bind.annotation.XmlElements;
  import javax.xml.bind.annotation.XmlType;
  
  @XmlType(name = "RootType")
  @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
  public class RootType {
  
      @XmlElements({
          @XmlElementSequence(Sequencepart.class), 
          @XmlElement(name="P", type=P.class), 
          @XmlElement(name="Q", type=Q.class)
          })
      public Object partA;
  
  }
  
  
  package uk.co.his.test.complexSequenceAndChoice.manual5;
  
  import javax.xml.bind.annotation.XmlElement;
  
  import uk.co.his.test.complexSequenceAndChoice.generated.nact1.A;
  import uk.co.his.test.complexSequenceAndChoice.generated.nact1.B;
  
  @XmlElementSequenceDef(propOrder = {
      "a",
      "b",
      "c"
  })
  public class Sequencepart {
  
      @XmlElement(name = "A")
      protected A a;
      @XmlElement(name = "B")
      protected B b;
      @XmlElement(name = "C")
  
  }
  </code></pre>
  
  <p>The marshaller would be relatively simple. The Unmarshaller would have to know to create a Sequencepart when it saw the start of an "A" element tag, and to insert the A values inside that Sequencepart instance.</p>
  
  <p>I have asked <a href="https://www.eclipse.org/forums/index.php/t/1071162/" rel="nofollow">this on the MOXy site</a>, and included a sample Maven project.</p>