2009-10-03 6 views
24

Je rencontre des problèmes avec la génération de classes Java avec des annotations JAXB appropriées à partir d'un XSD utilisant XJC.Comment générer des classes @XmlRootElement pour des types de base dans XSD?

J'ai un fichier XSD relativement simple définissant mon schéma XML. Les types complexes dans le XSD profitent de l'héritage en utilisant les balises <xs:extension>. Le problème que j'ai, c'est que j'ai besoin de tous les types complexes pour générer des classes Java avec le @XmlRootElement.

Malheureusement, la façon dont XJC génère les classes signifie que seule la classe dérivée obtient le @XmlRootElement (pas la classe de base). J'utilise la directive de liaison globale simple pour s'assurer qu'elle résout beaucoup d'autres problèmes que j'ai rencontrés avec XJC.

Voici un extrait d'exemple 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> 

Comme on peut le voir dans l'extrait ci-dessus, EmailArtifact étend Artifact.

Le code de classe java pour EmailArtifact contient les éléments suivants:

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

Le code de classe java pour Artifact contient les éléments suivants:

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

Dans le EmailArtifact, nous pouvons voir qu'il contient le @XmlRootElement mais le type de base Artifact ne contient pas @XmlRootElement.

Comment pouvez-vous forcer XJC à générer @XmlRootElement pour toutes les classes, y compris les types de base.

+0

mode de liaison simple doit faire. Êtes-vous sûr de le spécifier correctement? – skaffman

+0

Ouais assez confiant que je suis - est ici le sommet de ma XSD avec les globalBindings pertinentes ... " 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

Ouais, cela devrait fonctionner, je pense, bien que j'ai toujours utilisé des personnalisations de liaison externes plutôt que celles en ligne – skaffman

Répondre

3

Ce question fait référence à un message par blog Kohsuke Kawaguchi, a travaillé auparavant sur la JAX-B ou JAX-WS RI, qui parle de prise de décision du RI processus et le manque de clarté sur cette question dans les spécifications.

Le blog mentionne que la fonction de liaison simple fait partie du RI. Utilisez-vous le RI pour générer votre code?

28

bind utilisant XJB fichier:

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

Et ne pas oublier de définir l'élément du même type:

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

Merci! C'est la meilleure solution. Cela n'a pas besoin de modifier le schéma xsd et n'a pas besoin de modifier la classe racine générée. –

+0

Pourriez-vous expliquer la deuxième partie sur la nécessité de définir et l'élément du même type? Où est-ce défini? J'espérais ne pas changer le XSD ou générer des classes. – iX3

+2

Cela a fonctionné pour moi aussi. Les deux propriétés dans jxb: bindings ne sont pas nécessaires. De plus, j'ai dû fournir le compilateur xjc avec le paramètre extension = true en ligne de commande (dans un Ant-Script). – Heri

Questions connexes