I have 3 XML schemas:
A.xsd (provided to me and cannot be modified)
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://readonly.com/cantChangeXsd" targetNamespace="http://readonly.com/cantChangeXsd" elementFormDefault="qualified" attributeFormDefault="unqualified" version="3">
<xs:element name="RootElement" nillable="false">
<xs:complexType>
<xs:sequence>
<xs:element ref="ElementA" minOccurs="0"/>
<xs:any namespace="##other" processContents="lax" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ElementA" nillable="false">
<xs:annotation>
<xs:documentation>Element exists in original schema provided to me</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="attribute1" use="optional">
<xs:annotation>
<xs:documentation>The first attribute</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:whiteSpace value="preserve"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="attribute2" use="optional">
<xs:annotation>
<xs:documentation>The second attribute</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
B.xsd (imports A.xsd and defines another complex type specific to my use-case)
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sat="http://satbot.com/example" xmlns:ven="http://readonly.com/cantChangeXsd" targetNamespace="http://satbot.com/example" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.2">
<!--************************************************************************************************-->
<xsd:import namespace="http://readonly.com/cantChangeXsd" schemaLocation="A.xsd"/>
<xsd:complexType name="ElementBType">
<xsd:sequence>
<xsd:element name="ElementBDateTime" type="xsd:dateTime"/>
</xsd:sequence>
</xsd:complexType>
C.xsd (includes B.xsd and adds the new element that was defined to the schema)
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://satbot.com/example" targetNamespace="http://satbot.com/example" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.2">
<xsd:include schemaLocation="B.xsd"/>
<xsd:element name="ElementB" type="ElementBType" nillable="false">
<xsd:annotation>
<xsd:documentation>Element that is added for my use-case</xsd:documentation>
</xsd:annotation>
</xsd:element>
I've used the following command to generate java classes from these schemas:
xjc C.xsd -p com.satbot.xml
I am trying to generate JAXB classes from Schema and I select C.xsd as the source. The plan is to unmarshall from C.xml shown below:
<?xml version="1.0" encoding="UTF-8"?>
<RootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://readonly.com/cantChangeXsd" xmlns:sat="http://satbot.com/example" xsi:schemaLocation="C.xsd">
<ElementA attribute1="value1" attribute2="value2"/>
<sat:ElementB>
<sat:ElementBDateTime>2017-07-21T00:00:00Z</sat:ElementBDateTime>
</sat:ElementB>
</RootElement>
All complex types are successfully generated in separate java classes, however I can't see any way of accessing the contents of ElementB from an instance of the RootElement class. How can I access ElementB?
The generated classes are included below:
ElementA.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2017.07.24 at 12:14:55 PM AEST
//
package com.satbot.xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.w3c.dom.Element;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element ref="{http://readonly.com/cantChangeXsd}ElementA" minOccurs="0"/>
* <any processContents='lax' namespace='##other' minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"elementA",
"any"
})
@XmlRootElement(name = "RootElement")
public class RootElement {
@XmlElement(name = "ElementA")
protected ElementA elementA;
@XmlAnyElement(lax = true)
protected Object any;
/**
* Gets the value of the elementA property.
*
* @return
* possible object is
* {@link ElementA }
*
*/
public ElementA getElementA() {
return elementA;
}
/**
* Sets the value of the elementA property.
*
* @param value
* allowed object is
* {@link ElementA }
*
*/
public void setElementA(ElementA value) {
this.elementA = value;
}
/**
* Gets the value of the any property.
*
* @return
* possible object is
* {@link Object }
* {@link Element }
*
*/
public Object getAny() {
return any;
}
/**
* Sets the value of the any property.
*
* @param value
* allowed object is
* {@link Object }
* {@link Element }
*
*/
public void setAny(Object value) {
this.any = value;
}
}
ElementBType.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2017.07.20 at 05:40:04 PM AEST
//
package com.satbot.xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;
/**
* <p>Java class for ElementBType complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="ElementBType">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="ElementBDateTime" type="{http://www.w3.org/2001/XMLSchema}dateTime"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ElementBType", namespace = "http://satbot.com/example", propOrder = {
"elementBDateTime"
})
public class ElementBType {
@XmlElement(name = "ElementBDateTime", required = true)
@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar elementBDateTime;
/**
* Gets the value of the elementBDateTime property.
*
* @return
* possible object is
* {@link XMLGregorianCalendar }
*
*/
public XMLGregorianCalendar getElementBDateTime() {
return elementBDateTime;
}
/**
* Sets the value of the elementBDateTime property.
*
* @param value
* allowed object is
* {@link XMLGregorianCalendar }
*
*/
public void setElementBDateTime(XMLGregorianCalendar value) {
this.elementBDateTime = value;
}
}
ObjectFactory.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2017.07.20 at 05:40:04 PM AEST
//
package com.satbot.xml;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the com.satbot.xml package.
* <p>An ObjectFactory allows you to programatically
* construct new instances of the Java representation
* for XML content. The Java representation of XML
* content can consist of schema derived interfaces
* and classes representing the binding of schema
* type definitions, element declarations and model
* groups. Factory methods for each of these are
* provided in this class.
*
*/
@XmlRegistry
public class ObjectFactory {
private final static QName _ElementB_QNAME = new QName("http://satbot.com/example", "ElementB");
/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.satbot.xml
*
*/
public ObjectFactory() {
}
/**
* Create an instance of {@link ElementBType }
*
*/
public ElementBType createElementBType() {
return new ElementBType();
}
/**
* Create an instance of {@link RootElement }
*
*/
public RootElement createRootElement() {
return new RootElement();
}
/**
* Create an instance of {@link ElementA }
*
*/
public ElementA createElementA() {
return new ElementA();
}
/**
* Create an instance of {@link JAXBElement }{@code <}{@link ElementBType }{@code >}}
*
*/
@XmlElementDecl(namespace = "http://satbot.com/example", name = "ElementB")
public JAXBElement<ElementBType> createElementB(ElementBType value) {
return new JAXBElement<ElementBType>(_ElementB_QNAME, ElementBType.class, null, value);
}
}
package-info.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2017.07.20 at 05:40:04 PM AEST
//
@javax.xml.bind.annotation.XmlSchema(namespace = "http://readonly.com/cantChangeXsd", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.satbot.xml;
RootElement.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2017.07.20 at 05:40:04 PM AEST
//
package com.satbot.xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element ref="{http://readonly.com/cantChangeXsd}ElementA" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"elementA"
})
@XmlRootElement(name = "RootElement")
public class RootElement {
@XmlElement(name = "ElementA")
protected ElementA elementA;
/**
* Gets the value of the elementA property.
*
* @return
* possible object is
* {@link ElementA }
*
*/
public ElementA getElementA() {
return elementA;
}
/**
* Sets the value of the elementA property.
*
* @param value
* allowed object is
* {@link ElementA }
*
*/
public void setElementA(ElementA value) {
this.elementA = value;
}
}
The thing you initially left out of A.xsd (the <xs:any>) is very important! Otherwise it would not have been valid for RootElement to contain ElementB. Also, when you add this, xjc will generate another field named any in the class for RootElement, of type Object, along with a getAny and setAny method. It's through this field that you can get the ElementB. Example:
JAXBContext jaxbContext = JAXBContext.newInstance(RootElement.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
RootElement root;
try (InputStream in = SatBot.class.getResourceAsStream("/C.xml")) {
root = (RootElement) unmarshaller.unmarshal(in);
}
// Get ElementB from the field 'any' in RootElement
JAXBElement<ElementBType> jaxbElement = (JAXBElement<ElementBType>) root.getAny();
ElementBType elementB = jaxbElement.getValue();
System.out.println(elementB.getElementBDateTime());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With