Как я могу генерировать Java-классы для десериализации XML с использованием XML-схемы? - PullRequest
7 голосов
/ 30 августа 2011

Мне нужен простой способ генерировать классы Java из схемы, чтобы можно было легко десериализовать xml и интерпретировать с помощью объектов.

Использование Jaxb было бы здорово, но я открыт для любой средыэто сделает то же самое.Схема является схемой HL7 CDA.Это очень сложно, и я предполагаю, что именно поэтому у меня проблемы с ним.

Я пытался использовать xjc и JAXB (это было бы идеально), но я получаю следующую ошибку

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)

Ответы [ 4 ]

6 голосов
/ 30 августа 2011

Если эта проблема вызвана сложным типом, имеющим как атрибут, так и элемент с одинаковым именем, то вы можете использовать файл привязок схемы JAXB, чтобы изменить имя поля, соответствующее одному из узлов XML:

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

Если проблема возникает из-за того, что элемент появляется несколько раз в последовательности (т. Е. Как внутри, так и снаружи структуры выбора).Вам потребуется использовать следующее расширение XJC:

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

Полный пример см.

Ссылки по теме на схему CDA JAXB и HL7

0 голосов
/ 16 июня 2017

Информация об исключении: java.lang.IllegalArgumentException: попытка создать одно и то же поле дважды.

Как говорит исключение, вы пытаетесь сгенерировать код (JAXB) для схемы, имеющей одно и то же имя для нескольких атрибутов и элементов.Самый простой обходной путь - добавить файл JAXB-Binding.

Назначение JAXB-Binding: Этот файл используется для указания псевдонимов для повторяющихся элементов / атрибутов, т. Е. Если имя «id» повторяется, вы можете указать псевдоним как «id1»."с путем этого элемента / атрибута.

Пример файла привязки:

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

Если вы используете IDE NETBEANS для привязки JAXB, добавьте файл привязки во время создания и проверьтефлажок «Расширение», поскольку используется XJC.

0 голосов
/ 30 августа 2011

Eclipse EMF может генерировать классы из вашей схемы xsd с поддержкой (de) сериализации. EMF также можно использовать в автономных (не OSGi) приложениях.

0 голосов
/ 30 августа 2011

Я думаю, что вы, возможно, нажали http://java.net/jira/browse/JAXB-512

JiBX (http://jibx.sourceforge.net/) - это другая альтернатива, которая лучше с точки зрения производительности, чем JAXB. Хотя она требует создания файла конфигурации - но есть инструменты, которыеможет генерировать их автоматически для вас. Подробнее здесь -> http://jibx.sourceforge.net/fromschema/index.html

...