【问题标题】:How can I generate java classes for xml deserialization using an xml schema?如何使用 xml 模式生成用于 xml 反序列化的 java 类?
【发布时间】:2011-08-30 04:18:58
【问题描述】:

我想要一种从模式生成 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)

【问题讨论】:

  • 你有你想要生成的 XSD 的链接吗?

标签: java xsd jaxb


【解决方案1】:

如果此问题是由具有相同名称的属性和元素的复杂类型引起的,那么您可以使用 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>

完整示例见

到 JAXB 和 HL7 CDA 架构的相关链接

【讨论】:

    【解决方案2】:

    我想你可能打过http://java.net/jira/browse/JAXB-512

    JiBX(http://jibx.sourceforge.net/) 是另一种在性能方面比 JAXB 更好的替代方案。虽然它需要创建一个配置文件 - 但是有一些工具可以为您自动生成它们。更多细节在这里->http://jibx.sourceforge.net/fromschema/index.html

    【讨论】:

      【解决方案3】:

      Eclipse EMF 可以从您的 xsd 方案生成类,并支持(反)序列化。 EMF 也可以在独立(非 OSGi)应用程序中使用。

      【讨论】:

        【解决方案4】:

        异常信息: java.lang.IllegalArgumentException:试图创建相同的字段两次。

        正如异常所说,您正在尝试为多个属​​性和元素具有相同名称的模式生成代码 (JAXB)。最简单的解决方法是添加一个 JAXB 绑定文件。

        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>
        

        如果您使用 NETBEANS IDE 进行 JAXB 绑定,请在创建期间添加绑定文件,并选中“扩展”复选框,因为正在使用 XJC。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-05-07
          • 2011-02-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多