7 votes

Comment puis-je générer des classes java pour la désérialisation de xml en utilisant un schéma xml ?

J'aimerais disposer d'un moyen facile de générer des classes Java à partir d'un schéma afin de pouvoir facilement désérialiser le xml et l'interpréter à l'aide des objets.

L'utilisation de Jaxb serait parfaite, mais je suis ouvert à tout cadre de travail permettant d'accomplir la même chose. Le schéma est le schéma HL7 CDA. Il est très complexe et je suppose que c'est la raison pour laquelle j'ai des problèmes avec lui.

J'ai essayé d'utiliser xjc et JAXB (ce qui serait idéal) mais j'obtiens l'erreur suivante

xjc -d ~/code/ccd/java -p net.msdelta.cda -xmlschema -verbose CDA.xsd 
parsing a schema...
compiling a schema...
[INFO] generating code
unknown location
Exception in thread "main" java.lang.IllegalArgumentException: trying to create the same field twice: id
    at com.sun.codemodel.internal.JDefinedClass.field(JDefinedClass.java:408)
    at com.sun.codemodel.internal.JDefinedClass.field(JDefinedClass.java:379)
    at com.sun.tools.internal.xjc.generator.bean.field.AbstractFieldWithVar.createField(AbstractFieldWithVar.java:61)
    at com.sun.tools.internal.xjc.generator.bean.field.SingleField.<init>(SingleField.java:78)
    at com.sun.tools.internal.xjc.generator.bean.field.SingleField.<init>(SingleField.java:65)
    at sun.reflect.GeneratedConstructorAccessor8.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.sun.tools.internal.xjc.generator.bean.field.GenericFieldRenderer.generate(GenericFieldRenderer.java:53)
    at com.sun.tools.internal.xjc.generator.bean.field.DefaultFieldRenderer.generate(DefaultFieldRenderer.java:68)
    at com.sun.tools.internal.xjc.generator.bean.BeanGenerator.generateFieldDecl(BeanGenerator.java:736)
    at com.sun.tools.internal.xjc.generator.bean.BeanGenerator.generateClassBody(BeanGenerator.java:524)
    at com.sun.tools.internal.xjc.generator.bean.BeanGenerator.<init>(BeanGenerator.java:224)
    at com.sun.tools.internal.xjc.generator.bean.BeanGenerator.generate(BeanGenerator.java:164)
    at com.sun.tools.internal.xjc.model.Model.generateCode(Model.java:275)
    at com.sun.tools.internal.xjc.Driver.run(Driver.java:332)
    at com.sun.tools.internal.xjc.Driver.run(Driver.java:180)
    at com.sun.tools.internal.xjc.Driver._main(Driver.java:105)
    at com.sun.tools.internal.xjc.Driver.access$000(Driver.java:63)
    at com.sun.tools.internal.xjc.Driver$1.run(Driver.java:85)

8voto

Blaise Doughan Points 75613

Si ce problème est causé par un type complexe ayant à la fois un attribut et un élément avec le même nom, vous pouvez utiliser un fichier de liaisons de schéma JAXB pour changer le nom du champ correspondant à l'un des nœuds XML :

        <jxb:bindings node="//xs:attributeGroup[@name='db.common.attributes']/xs:attribute[@name='version']">
            <jxb:property name="commonVersion"/>
        </jxb:bindings>

Si le problème se produit parce que l'élément apparaît plusieurs fois dans une séquence (c'est-à-dire à la fois à l'intérieur et à l'extérieur d'une structure de choix). Vous devrez alors utiliser l'extension XJC suivante :

<jxb:globalBindings>
    <xjc:simple />
</jxb:globalBindings>

Pour un exemple complet, voir

Liens connexes vers JAXB et le schéma CDA de HL7

1voto

Arun Pratap Points 19

Informations sur les exceptions : java.lang.IllegalArgumentException : tentative de créer deux fois le même champ.

Comme le dit l'exception, vous essayez de générer du code (JAXB) pour un schéma ayant le même nom pour plusieurs attributs et éléments. La solution la plus simple consiste à ajouter un fichier JAXB-Binding.

Objectif de JAXB-Binding : Ce fichier est utilisé pour spécifier des noms d'alias pour les éléments/attributs répétés. Par exemple, si le nom "id" est répété, vous pouvez spécifier un nom d'alias comme "id1" avec le chemin de cet élément/attribut.

Exemple de fichier de reliure :

<jxb:globalBindings>
    <xjc:simple />
</jxb:globalBindings>

<jxb:bindings schemaLocation="Sample.xsd">        
    <!-- ATTRIBUTES -->
    <jxb:bindings node="//xs:element[@name='sample']/xs:complexType/xs:attribute[@name='id']">
        <jxb:property name="id1"/>
    </jxb:bindings>        
    <jxb:bindings node="//xs:element[@name='innersample']/xs:complexType/xs:attribute[@name='id']">
        <jxb:property name="id2"/>
    </jxb:bindings> 

    <!-- ELEMENTS -->                                 
    <jxb:bindings node="//xs:element[@name='sample']/xs:complexType/xs:sequence/xs:element[@name='ID']">
        <jxb:property name="id3"/>
    </jxb:bindings>
    <jxb:bindings node="//xs:element[@name='innersample']/xs:complexType/xs:sequence/xs:element[@name='ID']">
        <jxb:property name="id4"/>
    </jxb:bindings>
</jxb:bindings>

Si vous utilisez NETBEANS IDE pour JAXB Binding, ajoutez le fichier Binding pendant la création, et cochez la case "Extension", car XJC est utilisé.

0voto

Manish Points 2462

Je pense que tu as peut-être touché http://java.net/jira/browse/JAXB-512

JiBX(http://jibx.sourceforge.net/) est une autre alternative qui est meilleure en termes de performances que JAXB. Elle nécessite cependant la création d'un fichier de configuration - mais il existe des outils qui peuvent les générer automatiquement pour vous. Plus de détails ici ->http://jibx.sourceforge.net/fromschema/index.html

0voto

Nikolay Kasyanov Points 503

Eclipse EMF peut générer des classes à partir de votre schéma xsd, avec un support de (dé)sérialisation. EMF peut également être utilisé dans des applications autonomes (non-OSGi).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X