2009-10-03 23 views
24

Tengo algunos problemas para generar clases Java con anotaciones JAXB apropiadas de un XSD usando XJC.Cómo generar clases @XmlRootElement para tipos de base en XSD?

Tengo un archivo XSD relativamente simple que define mi esquema XML. Los tipos complejos dentro del XSD aprovechan la herencia usando las etiquetas <xs:extension>. El problema que tengo es que necesito todos los tipos complejos para generar clases de Java con el @XmlRootElement.

Desafortunadamente, la forma en que XJC genera las clases significa que solo la clase derivada obtiene el @XmlRootElement (no la clase base). Estoy usando la directiva de enlace global simple para asegurarme de que resuelve muchos de los otros problemas que he enfrentado con XJC.

Aquí es un fragmento de ejemplo de la XSD:

<xs:schema version="1.0" targetNamespace="http://www.knowledgemill.com/kmcs" 
    xmlns:kmcs="http://www.knowledgemill.com/kmcs" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    jaxb:version="2.0" 
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
    jaxb:extensionBindingPrefixes="xjc" 
    elementFormDefault="qualified"> 
    <xs:annotation> 
     <xs:appinfo> 
      <jaxb:globalBindings> 
       <xjc:simple /> 
      </jaxb:globalBindings> 
     </xs:appinfo> 
    </xs:annotation> 

    <xs:element name="Artifact" type="kmcs:Artifact"/> 
    <xs:element name="EmailArtifact" type="kmcs:EmailArtifact"/> 

    <xs:complexType name="Artifact"> 
     <xs:sequence> 
      <xs:element name="artifactId" type="xs:string" minOccurs="0"/> 
      <xs:element name="artifactType" type="xs:string" minOccurs="0"/> 
      <xs:element name="contentHash" type="xs:string" minOccurs="0"/> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="EmailArtifact"> 
     <xs:complexContent> 
      <xs:extension base="kmcs:Artifact"> 
       <xs:sequence> 
        <xs:element name="subject" type="xs:string" minOccurs="0"/> 
        <xs:element name="threadSubject" type="xs:string" minOccurs="0"/> 
        <xs:element name="from" type="xs:string" minOccurs="0"/> 
        <xs:element name="to" type="xs:string" minOccurs="0"/> 
        <xs:element name="cc" type="xs:string" minOccurs="0"/> 
        <xs:element name="bcc" type="xs:string" minOccurs="0"/> 
        <xs:element name="messageId" type="xs:string" minOccurs="0"/> 
        <xs:element name="date" type="xs:date" minOccurs="0"/> 
        <xs:element name="size" type="xs:long" minOccurs="0"/> 
        <xs:element name="hasAttachment" type="xs:boolean" minOccurs="0"/> 
        <xs:element name="sensitivity" type="xs:string" minOccurs="0"/> 
        <xs:element name="headerHash" type="xs:string" minOccurs="0"/> 
       </xs:sequence> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 


</xs:schema> 

Como podemos ver en el fragmento anterior, EmailArtifact se extiende Artifact.

El código de clase java para EmailArtifact contiene lo siguiente:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "EmailArtifact", propOrder = { 
    "subject", 
    "threadSubject", 
    "from", 
    "to", 
    "cc", 
    "bcc", 
    "messageId", 
    "date", 
    "size", 
    "hasAttachment", 
    "sensitivity", 
    "headerHash" 
}) 
@XmlSeeAlso({ 
    ExtendedEmail.class 
}) 
@XmlRootElement(name = "EmailArtifact") 
public class EmailArtifact 
    extends Artifact 
{ 

    protected String subject; 
    protected String threadSubject; 
    protected String from; 
    protected String to; 
    protected String cc; 
    protected String bcc; 
    protected String messageId; 
    @XmlSchemaType(name = "date") 
    protected XMLGregorianCalendar date; 
    protected Long size; 
    protected Boolean hasAttachment; 
    protected String sensitivity; 
    protected String headerHash; 

El código de clase java para Artifact contiene lo siguiente:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "Artifact", propOrder = { 
    "artifactId", 
    "artifactType", 
    "contentHash" 
}) 
@XmlSeeAlso({ 
    ManagedDocArtifact.class, 
    EmailArtifact.class 
}) 
public class Artifact { 

    protected String artifactId; 
    protected String artifactType; 
    protected String contentHash; 

En el EmailArtifact podemos ver que contiene el @XmlRootElement pero el tipo de base Artifact no contiene @XmlRootElement.

Cómo puede forzar a XJC a generar @XmlRootElement para todas las clases, incluidos los tipos de base.

+0

modo de unión simple debe hacer eso. ¿Estás seguro de que lo estás especificando correctamente? Sí – skaffman

+0

bastante seguro de que estoy - aquí está la parte superior de mi XSD con las pertinentes globalBindings ... " xmlns: xs =" http://www.w3.org/2001/XMLSchema " xmlns: jaxb =" http://java.sun.com/xml/ns/jaxb " jaxb: version =" 2.0 " xmlns: xjc =" http: //java.sun.com/xml/ns/jaxb/xjc" jaxb: extensionBindingPrefixes = "xjc" > jallch

+0

Sí, eso debería funcionar, creo, aunque siempre he usado personalizaciones de enlaces externos en lugar de las en línea – skaffman

Respuesta

3

Este question referencias un puesto blog por Kohsuke Kawaguchi, anteriormente trabajó en la JAX-B o JAX-WS RI, que habla de la decisión del proceso de RI y la falta de claridad de decisiones sobre esta cuestión en la especificación.

La entrada del blog menciona que la función de enlace simple es parte de la RI. ¿Estás usando RI para generar tu código?

28

Sólo enlazar mediante xjb-archivo:

<?xml version="1.0"?> 
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jxb:extensionBindingPrefixes="xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <jxb:bindings schemaLocation="path/to/myschema.xsd" node="/xs:schema"> 
    <jxb:globalBindings> 
     <xjc:simple /> 
    </jxb:globalBindings> 
    </jxb:bindings> 
</jxb:bindings> 

Y no se olvide de definir los elementos del mismo tipo:

<xs:complexType name="Artifact" /> 
<xs:element name="artifact" type="Artifact"> 
+2

¡Gracias! Es la mejor solución. Esto no necesita cambiar el esquema xsd y no necesita cambiar la clase raíz generada. –

+0

¿Podría explicarnos la segunda parte sobre la necesidad de definir un elemento del mismo tipo? ¿Dónde está eso definido? Esperaba no cambiar el XSD o las clases generadas. – iX3

+2

Esto funcionó para mí también. Ambas propiedades en jxb: enlaces no son necesarios. Además, tuve que proporcionar el compilador xjc con la extensión = verdadero param de línea de comandos (dentro de un Ant-Script). – Heri

Cuestiones relacionadas