2011-08-30 68 views
6

我想要一个简单的方法从架构中生成Java类,以便我可以轻松地反序列化xml并使用这些对象进行解释。如何使用xml模式为xml反序列化生成java类?

使用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) 
+1

您是否尝试生成XSD链接? – momo

回答

6

如果这个问题是由具有两个具有相同名称的属性和元素则可以使用一个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架构

0

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

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

0

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

0

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

正如例外所述,您正尝试为具有多个属性和元素的相同名称的架构生成代码(JAXB)。最简单的解决方法是添加JAXB绑定文件。的JAXB的绑定

目的:这个文件用于为重复的元素指定别名/属性即如果重复“身份证”的名称,可以为“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是正在使用。