In the last post we were able to map complex xml elements to classes. However it is recommended to build complex types and associate them to elements.
We saw a similar thing in the example of simple elements.
For marshaling we need to create elements of type attributedAddress2. This is shown in the code for ObjectFactory:
We saw a similar thing in the example of simple elements.
- Define a top level type.
- Define elements of the specific type.
<element name="attributedAddress2" type="si:attributedAddressType" /> <complexType name="attributedAddressType"> <attribute name="city" type="string" use="optional" default="-" /> <attribute name="zipcode" type="integer" use="required" /> <attribute name="country" type="string" fixed="India" /> </complexType>The code generated by XJC in this case is as below:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "attributedAddressType") public class AttributedAddressType { @XmlAttribute protected String city; @XmlAttribute(required = true) protected BigInteger zipcode; @XmlAttribute protected String country; // same code as the previous example - setter getters }Here JAXB generated a class for the complex type. Hence we do not see the XmlRootElement annotation here.
For marshaling we need to create elements of type attributedAddress2. This is shown in the code for ObjectFactory:
private final static QName _AttributedAddress2_QNAME = new QName("http://test.com/xsd/simple/01/", "attributedAddress2"); @XmlElementDecl(namespace = "http://test.com/xsd/simple/01/", name = "attributedAddress2") public JAXBElement<AttributedAddressType> createAttributedAddress2( AttributedAddressType value) { return new JAXBElement<AttributedAddressType>( _AttributedAddress2_QNAME, AttributedAddressType.class, null, value); } public AttributedAddressType createAttributedAddressType() { return new AttributedAddressType(); }To get the xml representation :
static void testMarshal() throws JAXBException { final ObjectFactory objectFactory = new ObjectFactory(); AttributedAddressType addressType = objectFactory .createAttributedAddressType(); addressType.setCity("Pune"); addressType.setZipcode(BigInteger.valueOf(411020)); JAXBElement<AttributedAddressType> address2 = objectFactory .createAttributedAddress2(addressType); final JAXBContext jContext = JAXBContext .newInstance(AttributedAddressType.class); final Marshaller marshaller = jContext.createMarshaller(); final StringWriter stringWriter = new StringWriter(); marshaller.marshal(address2, stringWriter); System.out.println(stringWriter.toString()); }And the output is :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <attributedAddress2 zipcode="411020" city="Pune" xmlns="http://test.com/xsd/simple/01/" />To convert back this XML to java:
static void testUnmarshal() throws JAXBException { final JAXBContext jContext = JAXBContext .newInstance(AttributedAddressType.class); final Unmarshaller unmarshaller = jContext.createUnmarshaller(); final StreamSource source = new StreamSource( TestComplexElements.class .getResourceAsStream("/AttributedAddress2.xml")); AttributedAddressType address1 = unmarshaller.unmarshal(source, AttributedAddressType.class).getValue(); System.out.println(address1.getCity() + ", " + address1.getCountry() + " - " + address1.getZipcode()); }Some might find this absence of class an irritant. Working with JAXBElement is not the only way here. For this we need to define the xsd as below:
<element name="addressInstance"> <complexType> <sequence> <element name="address" type="si:attributedAddressType" /> </sequence> </complexType> </element>The corresponding class generated by XJC is :
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = {"address"}) @XmlRootElement(name = "addressInstance") public class AddressInstance { @XmlElement(required = true) protected AttributedAddressType address; // setters and getters }
Great
ReplyDeleteWeb Designer in Bangalore