I'd like an easy way to generate Java classes from a schema so that I can easily deserialize xml and interpret using the objects.
Using Jaxb would be great, but I'm open to any framework that will accomplish the same thing. The schema is the HL7 CDA Schema. It's very complex and I'm guessing that's why I'm having problems with it.
I tried using xjc and JAXB (this would be ideal) but I get an the following error
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)
Jackson annotations are useful in defining and controlling the process of serialization and deserialization across various formats such as XML, JSON, and YAML.
If this problem is being caused by a complex type having both an attribute and element with the same name then you can use a JAXB schema bindings file to change the field name corresponding to one of the XML nodes:
<jxb:bindings node="//xs:attributeGroup[@name='db.common.attributes']/xs:attribute[@name='version']">
<jxb:property name="commonVersion"/>
</jxb:bindings>
If the problem is occurring because the element appears multiple times in a sequence (i.e. both inside and outside a choice structure). The you will need to use the following XJC extension:
<jxb:globalBindings>
<xjc:simple />
</jxb:globalBindings>
For a Complete Example See
Related Links to JAXB and HL7 CDA Schema
Exception Information : java.lang.IllegalArgumentException: trying to create the same field twice.
As the exception says, you are trying to generate code (JAXB) for a Schema having same name for multiple attributes and elements. The simplest work-around is to add a JAXB-Binding file.
Purpose of JAXB-Binding : This file is used to specify alias names for the repeated elements/attributes i.e. if "id" name is repeated, you can specify an alias name as "id1" with the path of that element/attribute.
Sample Binding File :
<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>
If you are using NETBEANS IDE for JAXB Binding, add the Binding file during creation, and check the "Extension" check box, as XJC is being used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With