web-dev-qa-db-fra.com

Comment générer des classes @XmlRootElement pour les types de base dans XSD?

J'ai des problèmes avec la génération de classes Java avec les annotations JAXB appropriées à partir d'un XSD utilisant XJC.

J'ai un fichier XSD relativement simple définissant mon schéma XML. Les types complexes dans le XSD tirent parti de l'héritage en utilisant le <xs:extension> Mots clés. Le problème que j'ai est que j'ai besoin de tous les types complexes pour générer Java Classes 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 simple directive de liaison globale pour m'assurer qu'elle résout bon nombre des autres problèmes que j'ai rencontrés avec XJC.

Voici un exemple d'extrait de 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 nous pouvons 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.

25
jallch

Liez simplement en utilisant le fichier xjb:

<?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 n'oubliez pas de définir un élément du même type:

<xs:complexType name="Artifact" />
<xs:element name="artifact" type="Artifact">
30
Azee

Cette question fait référence à un blog article de Kohsuke Kawaguchi, anciennement travaillé sur le JAX-B ou JAX-WS RI, qui parle du processus décisionnel du RI et du manque de clarté sur ce problème dans la spécification.

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

3
DavidValeri