Java HTML / XML How to - Marshal with XSD choice field in class








Question

We would like to know how to marshal with XSD choice field in class.

Answer

import java.io.StringReader;
//  w  ww .java2s.  c  o  m
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;

public class Main {

  public static void main(String[] args) throws Exception {
    JAXBContext jc = JAXBContext.newInstance(Foo.class, ObjectFactory.class);

    StringReader xml = new StringReader("<foo><C>Hello World</C></foo>");
    Unmarshaller unmarshaller = jc.createUnmarshaller();
    Foo foo = (Foo) unmarshaller.unmarshal(xml);

    JAXBElement<?> aOrBOrCOrD = foo.aOrBOrCOrD;
    System.out.println(aOrBOrCOrD.getName().getLocalPart());
    System.out.println(aOrBOrCOrD.getDeclaredType());
    System.out.println(aOrBOrCOrD.getValue());
  }

  @XmlRootElement
  @XmlAccessorType(XmlAccessType.FIELD)
  public static class Foo {

    @XmlElementRefs({ @XmlElementRef(name = "A", type = JAXBElement.class),
        @XmlElementRef(name = "B", type = JAXBElement.class),
        @XmlElementRef(name = "C", type = JAXBElement.class),
        @XmlElementRef(name = "D", type = JAXBElement.class) })
    protected JAXBElement<?> aOrBOrCOrD;

  }

  @XmlRegistry
  public static class ObjectFactory {

    @XmlElementDecl(name = "A")
    public JAXBElement<String> createA(String value) {
      return new JAXBElement<String>(new QName("A"), String.class, value);
    }

    @XmlElementDecl(name = "B")
    public JAXBElement<Integer> createB(Integer value) {
      return new JAXBElement<Integer>(new QName("B"), Integer.class, value);
    }

    @XmlElementDecl(name = "C")
    public JAXBElement<String> createC(String value) {
      return new JAXBElement<String>(new QName("C"), String.class, value);
    }

    @XmlElementDecl(name = "D")
    public JAXBElement<String> createD(String value) {
      return new JAXBElement<String>(new QName("D"), String.class, value);
    }

  }
}