partir online how generate generar from example classes clases xsd jaxb

online - Polimorfismo en esquema XSD y clases JAXB



xsd java xjc (4)

Use xs: extensión en su esquema y sus clases JAXB se heredarán (se extenderán) según lo defina en su esquema.

Tengo un xml como este:

<todo> <doLaundry cost="1"/> <washCar cost="10"/> <tidyBedroom cost="0" experiencePoints="5000"/> </todo>

Y el esquema XSD para esto es:

<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>

Y cuando proceso este esquema a través de JAXB obtengo una clase con un método como este:

public class Todo { public List<Object> getDoLaundryOrWashCarOrTidyBedroom() { ... } }

Idealmente, lo que me gustaría es una forma de definir un tipo de base genérico que extiendan todos los demás tipos de XSD. Las clases Jaxb generadas a partir del esquema XSD deben tener un método para devolver una lista de tareas genéricas. Esto haría que sea muy fácil agregar nuevas tareas a la lista de tareas pendientes:

public class Todo { public List<Task> getTasks() { ... } } public abstract class Task { public int getCost() { ... } } public class TidyBedroom extends Task { public int getExperiencePoints() { ... } }

¿Cómo debería ser el esquema XSD para generar las clases Java anteriores?



Encontré la respuesta con la ayuda del artículo de Blaise Doughan aquí: http://bdoughan.blogspot.com/2010/11/jaxb-and-inheritance-using-xsitype.html

Este esquema:

<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>

combinado con un archivo de enlace:

<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>

Darán clases abstractas y heredadas como describí en la pregunta. El archivo de enlace cambiará el nombre del método predeterminado de Jaxb de getDoLaundryOrWashCarOrTidyBedroom () a getTasks ().


Tal vez no estoy ''entendiendo'' la pregunta, pero ¿qué está mal con ...

<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>