XSD byte[][] issue on Web Service - xsd

I'm trying to pass to my web service something like an array of byte array (byte[][]) to do that i created this xsd file:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="FileResponse"
targetNamespace="http://tempuri.org/FileResponse.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/FileResponse.xsd"
xmlns:mstns="http://tempuri.org/FileResponse.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="FileResponse">
<xs:sequence>
<xs:element name="SPResultItem" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="file" type="xs:unsignedByte" minOccurs="0" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Message" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name="FileResponse" type="FileResponse"/>
</xs:schema>
XSD tool generates this:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/FileResponse.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/FileResponse.xsd", IsNullable=false)]
public partial class FileResponse {
private FileResponseSPResultStatus sPResultStatusField;
private sbyte[][] sPResultItemField;
private string messageField;
/// <remarks/>
public FileResponseSPResultStatus SPResultStatus {
get {
return this.sPResultStatusField;
}
set {
this.sPResultStatusField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("file", typeof(sbyte), IsNullable=false)]
public sbyte[][] SPResultItem {
get {
return this.sPResultItemField;
}
set {
this.sPResultItemField = value;
}
}
/// <remarks/>
public string Message {
get {
return this.messageField;
}
set {
this.messageField = value;
}
}
}
As you can see, the conversion seems good: the xsd contains a "sbyte[][]" field... But when i call a method from this webservice (even if it doesn't use this class) it crashes without giving infos...
How can i create an XSD that receives a sbyte[][] or byte[][] and works? Thank you very much!!

I solved this way:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="FileResponse"
targetNamespace="http://tempuri.org/FileResponse.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/FileResponse.xsd"
xmlns:mstns="http://tempuri.org/FileResponse.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="FileResponse">
<xs:sequence>
<xs:element name="SPResultItem" type="fileList" maxOccurs="unbounded"> </xs:element>
<xs:element name="Message" type="xs:string"></xs:element>
</xs:sequence>
<xs:complexType name ="fileList">
<xs:sequence>
<xs:element name="file" type="xs:base64Binary" ></xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name="FileResponse" type="FileResponse"/>

Related

jaxb2 & xjc - generate fields with inherited type

I'm having some trouble with an xsd that was supplied to us. I'm not really sure how to describe my issue without example so I created a test xsd that has the same issue.
Here's the xsd:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder" type="shipordertype"/> <!-- note: name is equal to name of a complex type further down -->
<xs:complexType name="shiptotype">
<xs:sequence>
<xs:element name="name" type="stringtype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="myshiptotype">
<xs:complexContent>
<xs:restriction base="shiptotype">
<xs:sequence>
<xs:element name="name" type="stringtype">
<xs:annotation>
<xs:documentation source="Yellow Field"/>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="shiporder">
<xs:sequence>
<xs:element name="orderperson" type="stringtype"/>
<xs:element name="shipto" type="shiptotype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="shipordertype">
<xs:complexContent>
<xs:restriction base="shiporder">
<xs:sequence>
<xs:element name="orderperson" type="stringtype"/>
<xs:element name="shipto" type="myshiptotype">
<xs:annotation>
<xs:documentation source="Yellow Field"/>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="stringtype">
<xs:restriction base="xs:string"/>
</xs:simpleType>
</xs:schema>
I've got this external binding file:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.1">
<jaxb:bindings schemaLocation="test.xsd" node="/xs:schema">
<jaxb:bindings node="//xs:complexType[#name='shiporder']">
<jaxb:class name="InnerShipOrder" />
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
Now when I generate java classes I get the following classes:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "shipordertype")
#XmlRootElement(name = "shiporder")
public class Shiporder
extends InnerShipOrder
implements Serializable
{
private final static long serialVersionUID = -1L;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "shiporder", propOrder = {
"orderperson",
"shipto"
})
#XmlSeeAlso({
Shiporder.class
})
public class InnerShipOrder
implements Serializable
{
private final static long serialVersionUID = -1L;
#XmlElement(required = true)
protected String orderperson;
#XmlElement(required = true)
protected Shiptotype shipto;
// some getter and setter functions
Now, in the xsd the shipordertype has a 'shipto' field of the type 'myshiptotype'. However in the generated classes, shipordertype extends shiporder which has a 'shipto' field of the type 'shiptotype'.
Is it possible to make it so that the generated ShipOrder class has a 'shipto' field of the 'myshiptotype'?

How to change XmlType of generated JAXB classes

I am using gradle to generate Java classes based on an XML Schema file. I am using 'org.glassfish.jaxb:jaxb-xjc:2.2.11' and 'org.glassfish.jaxb:jaxb-runtime:2.2.11' as dependencies so I can use the 'com.sun.tools.xjc.XJC2Task' class to generate the classes.
This is the schema file:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="test"
targetNamespace="urn:oio:records:1.0.0"
xmlns="urn:oio:records:1.0.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="records" type="recordsType"/>
<xs:element name="record" type="recordType"/>
<xs:complexType name="recordsType">
<xs:sequence>
<xs:element ref="record" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="recordType">
<xs:attribute name="key" type="xs:string"/>
<xs:attribute name="value" type="xs:string"/>
</xs:complexType>
</xs:schema>
One of the generated classes look like this:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "recordType")
public class RecordType {
#XmlAttribute(name = "key")
protected String key;
#XmlAttribute(name = "value")
protected String value;
public String getKey() {return key;}
public void setKey(String value) {this.key = value;}
public String getValue() {return value;}
public void setValue(String value) {this.value = value;}
}
How can I change the name value in the #XmlType annotation? I would like it to be
#XmlType(name = "record")
I have tried using a bindingsfile and tried to experiment with the <javaType> tag in the bindingsfile, but without luck.
EDIT:
The reason I need to change this is that I need to split an XML file using the stax splitter from Camel (http://camel.apache.org/stax.html section called "Iterate over a collection using JAXB and StAX").
This looks at the name attribute of the #XmlType annotation to recognize the xml tag to split on in the file. The recognized tag (<record>) will then be JAXB parsed to a RecordType java class.
The name in the #XmlType annotation is the name of the complexType in your schema file. This is how the parameter 'name' is defined for this annotation.
So, if you want to change it, you have to change the name of the complexType in your schema:
<xs:complexType name="record">
<xs:attribute name="key" type="xs:string"/>
<xs:attribute name="value" type="xs:string"/>
</xs:complexType>
You can use the jaxb2-annotate-plugin to override the value of the name attribute in the generated Java class.
For your code, it would look like this:
<xs:schema id="test"
targetNamespace="urn:oio:records:1.0.0"
xmlns="urn:oio:records:1.0.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:annox="http://annox.dev.java.net"
jaxb:extensionBindingPrefixes="annox"
elementFormDefault="qualified">
<xs:element name="records" type="recordsType"/>
<xs:element name="record" type="recordType"/>
<xs:complexType name="recordsType">
<xs:sequence>
<xs:element ref="record" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="recordType">
<xs:annotation>
<xs:appinfo>
<annox:annotate target="class">
#javax.xml.bind.annotation.XmlType(name = "record")
</annox:annotate>
</xs:appinfo>
</xs:annotation>
<xs:attribute name="key" type="xs:string"/>
<xs:attribute name="value" type="xs:string"/>
</xs:complexType>
</xs:schema>
I don't know if this should be considered a hack, but it does the trick. Interestingly enough, in my case even the namespace attribute of XmlType is still generated and filled with the same value as without adding that explicit annotation.

Problems creating DynamicEntities - DynamicHelper.createQuery: Dynamic type not found:

I seem to be having an issue that for the life of me I can not see why. I suspect it is a name space problem.
The following code always results in the following error: DynamicHelper.createQuery: Dynamic type not found:
I have tried numerous namespaces
"mmckenzie.stockcontrol/supplier"
"supplier"
"supplierDAO"
"mmckenzie.stockcontrol/supplierDAO"
I fully expect that this is going to be user error. Any guidence is most welcome.
JAVA CODE:
package model;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.xml.bind.JAXBException;
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class Test
{
public static void main(String[] args)
{
try {
URL schema = new URL("http://localhost:8080/stockcontrol/schema/stockcontrol.xsd");
InputStream xsd = schema.openStream();
EntityResolver er = new EntityResolver()
{
#Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
{
URL schema = new URL("http://localhost:8080/stockcontrol/schema/"+(new File(systemId)).getName());
InputStream xsd = schema.openStream();
InputSource is = new InputSource(xsd);
is.setSystemId(schema.getPath());
return is;
}
};
//create the context from the XSD
DynamicJAXBContext xmlContext = DynamicJAXBContextFactory.createContextFromXSD(xsd,er, null, null);
//create a DYNAMICEntity for the supplier object.
DynamicEntity de = xmlContext.newDynamicEntity("mmckenzie.stockcontrol/supplier");
}
catch (IOException | JAXBException e)
{
e.printStackTrace();
}
}
}
XSD
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="mmckenzie.stockcontrol" xmlns:tns="mmckenzie.stockcontrol" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="stockcontrol2.xsd"/>
<xs:element name="batch" type="tns:batchDAO"/>
<xs:element name="batches" type="tns:batchesDAO"/>
<xs:element name="component" type="tns:componentDAO"/>
<xs:element name="components" type="tns:componentsDAO"/>
<xs:element name="prefixes" type="tns:componentPrefixesDAO"/>
<xs:element name="product" type="tns:productDAO"/>
<xs:element name="product_batches" type="tns:productBatchesDAO"/>
<xs:element name="productbatch" type="tns:productBatchDAO"/>
<xs:element name="products" type="tns:productsDAO"/>
<xs:element name="supplier" type="tns:supplierDAO"/>
<xs:element name="suppliers" type="tns:suppliersDAO"/>
<xs:complexType name="batchesDAO">
<xs:sequence>
<xs:element name="batch" type="tns:batchDAO" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="batchDAO">
<xs:sequence>
<xs:element name="idbatch" type="xs:int"/>
<xs:element name="dateReceived" type="xs:long"/>
<xs:element name="dateConsumed" type="xs:long"/>
<xs:element name="invoice" type="xs:string" minOccurs="0"/>
<xs:element name="qty" type="xs:int"/>
<xs:element name="qtyInStock" type="xs:int"/>
<xs:element name="unitCost" type="xs:decimal" minOccurs="0"/>
<xs:element name="componentId" type="xs:int"/>
<xs:element name="supplierId" type="xs:int"/>
<xs:element name="unitType" type="unitType" minOccurs="0"/>
<xs:element name="isActive" type="xs:boolean"/>
<xs:element ref="tns:products" minOccurs="0"/>
<xs:element name="batchCost" type="xs:decimal" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="productsDAO">
<xs:sequence>
<xs:element name="product" type="tns:productDAO" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="productDAO">
<xs:sequence>
<xs:element name="idProduct" type="xs:int"/>
<xs:element name="cost" type="xs:decimal" minOccurs="0"/>
<xs:element name="description" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:int"/>
<xs:element name="sellPrice" type="xs:decimal" minOccurs="0"/>
<xs:element name="productBatches" type="tns:productBatchesDAO" minOccurs="0"/>
<xs:element name="date_sold" type="timestamp" minOccurs="0"/>
<xs:element name="date_produced" type="timestamp" minOccurs="0"/>
<xs:element ref="tns:components" minOccurs="0"/>
<xs:element name="hours_worked" type="xs:double"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="productBatchesDAO">
<xs:sequence>
<xs:element name="productbatches" type="tns:productBatchDAO" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="productBatchDAO">
<xs:sequence>
<xs:element ref="tns:component" minOccurs="0"/>
<xs:element ref="tns:batch" minOccurs="0"/>
<xs:element name="quantyUsed" type="xs:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="componentDAO">
<xs:sequence>
<xs:element name="idcomponent" type="xs:int"/>
<xs:element name="componentName" type="xs:string" minOccurs="0"/>
<xs:element ref="tns:batches" minOccurs="0"/>
<xs:element name="componentPrefix" type="componentPrefix" minOccurs="0"/>
<xs:element name="qtyInStock" type="xs:int"/>
<xs:element ref="tns:products" minOccurs="0"/>
<xs:element name="quantity" type="xs:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="componentsDAO">
<xs:sequence>
<xs:element name="component" type="tns:componentDAO" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="suppliersDAO">
<xs:sequence>
<xs:element name="supplier" type="tns:supplierDAO" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="supplierDAO">
<xs:sequence>
<xs:element name="idsupplier" type="xs:int"/>
<xs:element name="modified" type="timestamp" minOccurs="0"/>
<xs:element name="name" type="xs:string" minOccurs="0"/>
<xs:element ref="tns:batches" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="componentPrefixesDAO">
<xs:sequence>
<xs:element name="prefix" type="componentPrefix" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
All comments suggestions most welcome.
The way that it creates the namespaces is not what I was expecting. The correct answer for this example would be
DynamicEntity de = xmlContext.newDynamicEntity("stockcontrol.mmckenzie.SupplierDAO");
This article was useful in finding the resolution.
Appendix D: Binding XML Names to Java Identifiers" of the Java Architecture for XML Binding (JAXB) 2.2 Specification (http://jcp.org/en/jsr/detail?id=222)
However using the eclipse debugger I was able for find the Helper names spaces. To use this method follow these steps in eclipse (Mars in mycase).
start your app in debugger with a break point just after your DynamicJAXBContext code.
in the eclipse varibles tab, find your DynamicJAXBContext object.
(your context)->ContextState->Helpers->ElementData->(non null object)->fqClassNameToDescripters->table->(non null entry)->key
The key value will give you an idea of what namespace it is expecting.

Jaxb - Namespace problems with SchemaGen and java.util.Map

When a class contains a java.util.Map, SchemaGen generates an xsd with a namespace on the Map elements. However when the marshaller generates xml from the same class no namespace is present.
This may be solvable with XmlAdapter however that seems to require the creation of 3 extra classes per Map. As I have a large number of maps I don't want to go down this route.
Is there any way to get SchemaGen and the Marshaller to generate the same xml?
Example Classes and schemas:
Test1:
#XmlRootElement
public class Test1 implements Serializable {
private String field1;
private Map<String, Test2> attributes;
public Test1() {}
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public Map<String, Test2> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, Test2> attributes) {
this.attributes = attributes;
}
}
Test2:
public class Test2 implements Serializable {
private String name;
private String value;
public Test2() {
}
public Test2(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
SchemaGen output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://testns" xmlns:tns="http://testns" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="test1" type="tns:test1"/>
<xs:complexType name="test1">
<xs:sequence>
<xs:element name="attributes">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="key" minOccurs="0" type="xs:string"/>
<xs:element name="value" minOccurs="0" type="tns:test2"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="field1" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="test2">
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="0"/>
<xs:element name="value" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Xml that conforms to the schema. (note. jaxb will not unmarshall this xml!)
<?xml version="1.0" encoding="UTF-8"?>
<ns1:test1
xmlns:ns1="http://testns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xsi:schemaLocation="http://testns ../build/schemas/schema1.xsd"
>
<ns1:attributes>
<ns1:entry>
<ns1:key>a1</ns1:key>
<ns1:value>
<ns1:name>a1</ns1:name>
<ns1:value>v1</ns1:value>
</ns1:value>
</ns1:entry>
</ns1:attributes>
<ns1:field1>f1</ns1:field1>
</ns1:test1>
Xml that Jaxb produces. (note. It does not conform to the schema!)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:test1 xmlns:ns2="http://testns">
<ns2:attributes>
<entry>
<key>a1</key>
<value>
<ns2:name>a1</ns2:name>
<ns2:value>v1</ns2:value>
</value>
</entry>
</ns2:attributes>
<ns2:field1>f1</ns2:field1>
</ns2:test1>

Polymorphism in XSD schema and JAXB classes

I have an xml like this:
<todo>
<doLaundry cost="1"/>
<washCar cost="10"/>
<tidyBedroom cost="0" experiencePoints="5000"/>
</todo>
And the XSD schema for it is:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="todo">
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="doLaundry" type="doLaundry" />
<xs:element name="washCar" type="washCar" />
<xs:element name="tidyBedroom" type="tidyBedroom" />
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="doLaundry">
<xs:attribute name="cost" type="xs:int" />
</xs:complexType>
<xs:complexType name="washCar">
<xs:attribute name="cost" type="xs:int" />
</xs:complexType>
<xs:complexType name="tidyBedroom">
<xs:attribute name="cost" type="xs:int" />
<xs:attribute name="experiencePoints" type="xs:int" />
</xs:complexType>
</xs:schema>
And when I process this schema through JAXB I get a class with a method like this:
public class Todo {
public List<Object> getDoLaundryOrWashCarOrTidyBedroom() {
...
}
}
Ideally, what I would like is a way to define a generic base type that all the other XSD types extend. The Jaxb classes generated from the XSD schema should have a method to return a list of generic tasks. This would make it very easy to add new tasks to the todo list:
public class Todo {
public List<Task> getTasks() {
...
}
}
public abstract class Task {
public int getCost() {
...
}
}
public class TidyBedroom extends Task {
public int getExperiencePoints() {
...
}
}
What should the XSD schema look like in order to generate the above Java classes?
I found the answer with the help of Blaise Doughan's article here: http://bdoughan.blogspot.com/2010/11/jaxb-and-inheritance-using-xsitype.html
This schema:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="todo">
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="doLaundry" type="doLaundry" />
<xs:element name="washCar" type="washCar" />
<xs:element name="tidyBedroom" type="tidyBedroom" />
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType abstract="true" name="Task">
<xs:attribute name="cost" type="xs:int" use="required" />
</xs:complexType>
<xs:complexType name="doLaundry">
<xs:complexContent>
<xs:extension base="Task">
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="washCar">
<xs:complexContent>
<xs:extension base="Task">
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tidyBedroom">
<xs:complexContent>
<xs:extension base="Task">
<xs:attribute name="experiencePoints" type="xs:int" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
combined with a binding file:
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings>
<jxb:bindings schemaLocation="todo.xsd" node="/xs:schema/xs:complexType[#name='todo']/xs:sequence/xs:choice">
<jxb:property name="Tasks"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
Will give abstract and inherited classes as I described in the question. The binding file will change Jaxb's default method name from getDoLaundryOrWashCarOrTidyBedroom() to getTasks().
xsd:choice corresponds to the #XmlElements annotation. You could apply this annotation directly to your desired object model.
For more information see:
http://bdoughan.blogspot.com/2010/10/jaxb-and-xsd-choice-xmlelements.html
Use xs:extension in your schema and your JAXB classes will be inherited (extended) as you define in your schema.
Maybe I'm not 'getting' the question, but what is wrong with..
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="todo">
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="doLaundry" type="task" />
<xs:element name="washCar" type="task" />
<xs:element name="tidyBedroom" type="task" />
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="task">
<xs:attribute name="cost" type="xs:int" />
<xs:attribute name="experiencePoints" type="xs:int" />
</xs:complexType>
</xs:schema>

Resources