web-dev-qa-db-fra.com

Génération de classes Java à partir de XMLSchema.xsd à l'aide de JAXB

J'utilise jaxb pour générer des classes Java à partir d'un schéma xml . Le schéma importe XMLSchema.xsd et son contenu est utilisé en tant qu'élément du document.

Si je supprime l'importation et la référence à "xsd: schema" respectivement, le compilateur de liaisons génère avec succès les classes . Si je ne le fais pas, cela produirait les erreurs suivantes, qui sont les mêmes si j'essayais de générer Java. classes de XMLSchema.xsd uniquement!

>  C:\Users\me>"%JAXB%/xjc" -extension -d tmp/uisocketdesc -p uis.jaxb uisocketdesc.xsd -b xml_binding_test.xml -b xml_binding_test_2.xml
-b xml_binding_test_3.xml
parsing a schema...
compiling a schema...

> [ERROR] A class/interface with the same name "uis.jaxb.ComplexType" is already in use. Use a class customization to resolve this conflict.
 line 612 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "ComplexType" is generated from here.
 line 440 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.Attribute" is already in use. Use a class customization to resolve this conflict.
 line 364 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "Attribute" is generated from here.
 line 1020 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.SimpleType" is already in use. Use a class customization to resolve this conflict.
 line 2278 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "SimpleType" is generated from here.
 line 2222 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.Group" is already in use. Use a class customization to resolve this conflict.
 line 930 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "Group" is generated from here.
 line 727 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.AttributeGroup" is already in use. Use a class customization to resolve this conflict.
 line 1062 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "AttributeGroup" is generated from here.
 line 1026 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.Element" is already in use. Use a class customization to resolve this conflict.
 line 721 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "Element" is generated from here.
 line 647 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 1020 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 364 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 2278 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 2222 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 930 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 727 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 440 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 612 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 1026 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 1062 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 647 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 721 of "http://www.w3.org/2001/XMLSchema.xsd"

Failed to produce code.
19
Christian Schulz

Combattre ce genre de choses aussi, pour moi, il s’agit d’un problème de respect de la casse et du même nom pour un problème d’élément et d’attribut (parfois par héritage). Pour le deuxième problème, j'utilise un fichier de liaison externe contenant quelque chose comme ceci: 

<jaxb:bindings node="//xs:complexType[@name='AbstractGriddedSurfaceType']//xs:attribute[@name='rows']">
    <jaxb:property name="rowCount"/>
</jaxb:bindings>

Pour les problèmes de casse, vous pouvez utiliser l'argument xjc -XautoNameResolution , la version maven est <args><arg>-B-XautoNameResolution</arg></args>, mais cela ne fonctionne pas pour les éléments d'encapsidation. Vous devez donc écrire les personnalisations jaxb comme indiqué ci-dessus, ... et si vous êtes malchanceux comme moi :) vous devrez peut-être utiliser une copie locale d’un xsd et corriger les duplications manuellement.

Éditer Une autre solution au problème de respect de la casse pour lequel renommer l’élément ne suffit pas:

<jaxb:bindings node=".//xs:element[@name='imageDatum'][@type='gml:ImageDatumPropertyType']">
    <jaxb:property name="imageDatumInst"/>
    <jaxb:factoryMethod name="imageDatumInst" />
</jaxb:bindings>

Bonne chance, j'espère que ça aide.

17
tomasb

Vous pouvez réussir à faire en sorte que JAXB génère du code pour XML Schema xsd en utilisant (au moins) deux méthodes. Le problème que vous rencontrez provient du fait que certains types de schéma et certains éléments portent les mêmes noms.


La première option évite les conflits de noms en appliquant une ou plusieurs transformations de noms XML aux noms de classe générés. Voici un exemple de fichier de liaison externe qui fera ceci:

<jxb:bindings version="2.1"
               xmlns:jxb="http://Java.Sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:xjc="http://Java.Sun.com/xml/ns/jaxb/xjc"
               jxb:extensionBindingPrefixes="xjc">  
  <jxb:globalBindings>
    <xjc:simple/>   
  </jxb:globalBindings>   
  <jxb:bindings schemaLocation="XMLSchema.xsd">
    <jxb:schemaBindings>
      <jxb:nameXmlTransform>
        <jxb:elementName suffix="Element"/>
      </jxb:nameXmlTransform>
    </jxb:schemaBindings>
  </jxb:bindings>  
</jxb:bindings>

Cette approche fonctionne (vous pouvez appliquer d'autres transformations qui fonctionneraient tout aussi bien, mais j'ai vu cette technique maintes et maintes fois dans la documentation), mais je pense que cela produit des résultats déplaisants. Par exemple, il existe dans ce cas une classe générée nommée ElementElement.


La deuxième approche utilise la personnalisation de classe comme suggéré par la sortie de xjc. En fait, la propriété abstract="true" est définie dans le type de schéma correspondant dans toutes les classes posant problème, sauf une. Par conséquent, il est logique que le nom de la classe soit précédé de "Abstract", c'est-à-dire AbstractElement. La classe Attribute restante n'est pas abstraite, mais le xs:element nommé attribute génère une classe d'extension avec un corps vide. C'est pourquoi je l'ai appelé BaseAttribute. Voici la définition de liaison externe que j'ai utilisée:

<jxb:bindings version="2.1"
               xmlns:jxb="http://Java.Sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:xjc="http://Java.Sun.com/xml/ns/jaxb/xjc"
               jxb:extensionBindingPrefixes="xjc">
  <jxb:globalBindings>
    <xjc:simple/>
  </jxb:globalBindings>
  <jxb:bindings schemaLocation="XMLSchema.xsd">
    <jxb:schemaBindings>
      <jxb:package name="org.w3.xmlschema"/>
    </jxb:schemaBindings>
    <jxb:bindings node="//xs:complexType[@name='complexType']">
      <jxb:class name="AbstractComplexType"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='group']">
      <jxb:class name="AbstractGroup"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='attributeGroup']">
      <jxb:class name="AbstractAttributeGroup"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='simpleType']">
      <jxb:class name="AbstractSimpleType"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='element']">
      <jxb:class name="AbstractElement"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='attribute']">
      <jxb:class name="BaseAttribute"/>
    </jxb:bindings> 
  </jxb:bindings>
</jxb:bindings>

Cela donne à mon avis des noms de classes générés plus clairs et compile avec succès le schéma.


Je recommanderais également d'utiliser une compilation séparée pour XMLSchema.xsd et de la conserver dans un fichier jar pour une utilisation ultérieure au cas où ce problème se poserait à nouveau lors de la compilation d'un autre schéma. Les réponses à cette question décrivent comment.

9
Keith Layne

On dirait que votre schéma est cassé. XJC est extrêmement pointilleux à propos de ces choses et peut échouer sur des choses laissées par d’autres outils.

Plutôt que de parcourir les erreurs de XJC, je trouve qu'il est plus facile d'exécuter le schéma via le vérificateur de qualité { AlphaWorks Schema Quality Checker }. Cela donne une belle sortie lisible par l’homme (enfin, par le développeur, de toute façon) de ce qui ne va pas. Si tout se passe bien, vous aurez beaucoup plus de chances de passer par XJC.

4
skaffman

Une autre option serait de supprimer l’option -p afin que les classes soient générées dans des packages différents.

3
Christos

J'ai rencontré le même problème lors de la génération d'objets à partir de .wsdl avec cxf. La solution pour moi consiste à utiliser -autoNameResolution comme le message d'erreur le suggère. Configuration Maven: 

         <wsdlOption>
                            <wsdl>${basedir}/test.wsdl</wsdl>
                            <extraargs>
                                <extraarg>-b</extraarg>     
                            <extraarg>http://www.w3.org/2001/XMLSchema.xsd</extraarg>
                                <extraarg>-autoNameResolution</extraarg>
                            </extraargs>
                            <packagenames>
                                <packagename>test.wsdl</packagename>
                            </packagenames>
                        </wsdlOption>
2
blue-sky

Je suis tombé sur la même erreur et enlevé <generatePackage></generatePackage> entièrement Cela a résolu mon problème.

0
Hamid Mohayeji

J'ai essayé de suivre et cela a fonctionné pour moi:

<jxb:bindings schemaLocation="ClaimActivity-ACORD.xsd">
    <jxb:schemaBindings>
        <jxb:package name="x.x.x.x" />
    </jxb:schemaBindings>
    <jxb:bindings node="//xsd:complexType[@name='ConstructionType']">
        <jxb:class name="AbstractConstructionType" />
    </jxb:bindings>
    <jxb:bindings node="//xsd:complexType[@name='ItemDefinitionType']">
        <jxb:class name="AbstractItemDefinitionType" />
    </jxb:bindings>
    <jxb:bindings node="//xsd:complexType[@name='LocationType']">
        <jxb:class name="AbstractLocationType" />
    </jxb:bindings>
    <jxb:bindings node="//xsd:complexType[@name='TaxFeeType']">
        <jxb:class name="AbstractTaxFeeType" />
    </jxb:bindings>
    <jxb:bindings node="//xsd:complexType[@name='DeductibleType']">
        <jxb:class name="AbstractDeductibleType" />
    </jxb:bindings>
    <jxb:bindings node="//xsd:complexType[@name='RegistrationType']">
        <jxb:class name="AbstractRegistrationType" />
    </jxb:bindings>
</jxb:bindings>

0