简体   繁体   English

使用JAXB从XMLSchema.xsd生成Java类

[英]Generating Java classes out of XMLSchema.xsd using JAXB

I'm using jaxb to generate java classes out of a xml schema. 我正在使用jaxb从xml架构生成java类。 The schema imports XMLSchema.xsd and its content is used as an element in the document. 模式导入XMLSchema.xsd,其内容用作文档中的元素。

If I remove the import and the reference to "xsd:schema" respectively then the binding compiler generates successfully the classes. 如果我分别删除导入和对“xsd:schema”的引用,那么绑定编译器会成功生成类。 If I do not then it would produce the following errors, which are the same if I would try to generate Java classes from the XMLSchema.xsd only! 如果我没有那么它会产生以下错误,如果我尝试仅从XMLSchema.xsd生成Java类,则会出现同样的错误!

>  C:\Users\me>"%JAXB%/xjc" -extension -d tmp/uisocketdesc -p uis.jaxb uisocketdesc.xsd -b xml_binding_test.xml -b xml_binding_test_2.xml
-b xml_binding_test_3.xml
parsing a schema...
compiling a schema...

> [ERROR] A class/interface with the same name "uis.jaxb.ComplexType" is already in use. Use a class customization to resolve this conflict.
 line 612 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "ComplexType" is generated from here.
 line 440 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.Attribute" is already in use. Use a class customization to resolve this conflict.
 line 364 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "Attribute" is generated from here.
 line 1020 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.SimpleType" is already in use. Use a class customization to resolve this conflict.
 line 2278 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "SimpleType" is generated from here.
 line 2222 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.Group" is already in use. Use a class customization to resolve this conflict.
 line 930 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "Group" is generated from here.
 line 727 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.AttributeGroup" is already in use. Use a class customization to resolve this conflict.
 line 1062 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "AttributeGroup" is generated from here.
 line 1026 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.Element" is already in use. Use a class customization to resolve this conflict.
 line 721 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "Element" is generated from here.
 line 647 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 1020 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 364 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 2278 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 2222 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 930 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 727 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 440 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 612 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 1026 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 1062 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 647 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 721 of "http://www.w3.org/2001/XMLSchema.xsd"

Failed to produce code.

Fighting such stuff as well, for me it is case-sensitivity issue and the same name for element and attribute issue (thru inheritance sometimes). 同样也要打这样的东西,对我而言,它是区分大小写的问题,并且元素和属性问题的名称相同(有时通过继承)。 For the second problem I'm using external binding file that contains something like this: 对于第二个问题,我正在使用包含以下内容的外部绑定文件:

<jaxb:bindings node="//xs:complexType[@name='AbstractGriddedSurfaceType']//xs:attribute[@name='rows']">
    <jaxb:property name="rowCount"/>
</jaxb:bindings>

For case-sensitivity issues you can use xjc argument -XautoNameResolution , maven version is <args><arg>-B-XautoNameResolution</arg></args> , but this doesn't work for wrapper elements, so for these you need to write jaxb customizations as mentioned above, ... and if you are unlucky like me :) you may need to use a local copy of an xsd and fix duplications manually. 对于区分大小写的问题,您可以使用xjc参数-XautoNameResolution ,maven版本是<args><arg>-B-XautoNameResolution</arg></args> ,但这对包装元素不起作用,因此对于这些需要写上面提到的jaxb自定义,...如果你不像我这样:)你可能需要使用xsd的本地副本并手动修复重复。

Edit Found another solution for the case-sensitivity issue where renaming the element isn't enough: 编辑找到另一个解决区分大小写问题的解决方案,其中重命名元素是不够的:

<jaxb:bindings node=".//xs:element[@name='imageDatum'][@type='gml:ImageDatumPropertyType']">
    <jaxb:property name="imageDatumInst"/>
    <jaxb:factoryMethod name="imageDatumInst" />
</jaxb:bindings>

Good luck, hope this helps. 祝你好运,希望这会有帮助。

You can successfully get JAXB to generate code for the XML Schema xsd by (at least) two methods. 您可以通过(至少)两种方法成功地让JAXB为XML Schema xsd生成代码。 The problem you are experiencing stems from the fact that some schema types and elements share the same names. 您遇到的问题源于某些模式类型和元素共享相同名称的事实。


The first option avoids name conflicts by applying one or more XML name transformations to the generated class names. 第一个选项通过将一个或多个XML名称转换应用于生成的类名来避免名称冲突。 Here is an example of an external binding file that will do this: 以下是将执行此操作的外部绑定文件的示例:

<jxb:bindings version="2.1"
               xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jxb:extensionBindingPrefixes="xjc">  
  <jxb:globalBindings>
    <xjc:simple/>   
  </jxb:globalBindings>   
  <jxb:bindings schemaLocation="XMLSchema.xsd">
    <jxb:schemaBindings>
      <jxb:nameXmlTransform>
        <jxb:elementName suffix="Element"/>
      </jxb:nameXmlTransform>
    </jxb:schemaBindings>
  </jxb:bindings>  
</jxb:bindings>

This approach works (you could apply other transforms that would work just as well, but I've seen this technique over and over in the documentation) but I think it produces ugly results. 这种方法有效(您可以应用其他可以正常工作的转换,但我在文档中一遍又一遍地看到这种技术),但我认为它会产生难看的结果。 For example, there is a generated class in this case named ElementElement . 例如,在这种情况下,生成的类名为ElementElement


The second approach uses class customization as suggested by the output of xjc. 第二种方法使用xjc输出建议的类定制。 In fact, all but one of the problem classes has the property abstract="true" set in the corresponding schema type. 实际上,除了一个问题类之外的所有问题类都在相应的模式类型中设置了属性abstract="true" Therefore it makes sense to me to prepend the class name with "Abstract", ie AbstractElement . 因此,使用“Abstract”(即AbstractElement类名称是有道理的。 The remaining Attribute class is not abstract, but the xs:element named attribute generates an extension class with an empty body. 剩下的Attribute类不是抽象的,但是xs:element named attribute生成一个带有空体的扩展类。 Therefore I called it BaseAttribute . 因此我称之为BaseAttribute Here is the external binding definition I used: 这是我使用的外部绑定定义:

<jxb:bindings version="2.1"
               xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jxb:extensionBindingPrefixes="xjc">
  <jxb:globalBindings>
    <xjc:simple/>
  </jxb:globalBindings>
  <jxb:bindings schemaLocation="XMLSchema.xsd">
    <jxb:schemaBindings>
      <jxb:package name="org.w3.xmlschema"/>
    </jxb:schemaBindings>
    <jxb:bindings node="//xs:complexType[@name='complexType']">
      <jxb:class name="AbstractComplexType"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='group']">
      <jxb:class name="AbstractGroup"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='attributeGroup']">
      <jxb:class name="AbstractAttributeGroup"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='simpleType']">
      <jxb:class name="AbstractSimpleType"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='element']">
      <jxb:class name="AbstractElement"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='attribute']">
      <jxb:class name="BaseAttribute"/>
    </jxb:bindings> 
  </jxb:bindings>
</jxb:bindings>

This gives clearer generated class names in my opinion, and successfully compiles the schema. 在我看来,这给出了更清晰的生成类名,并成功编译了模式。


I would also recommend using separate compilation for XMLSchema.xsd and keeping it in a jar file for later use in case this issue came up again while compiling another schema. 我还建议对XMLSchema.xsd使用单独的编译并将其保存在jar文件中以供以后使用,以防在编译另一个模式时再次出现此问题。 The answers to this question describe how. 这个问题的答案描述了如何。

It looks like your schema is broken. 看起来您的架构已损坏。 XJC is extremely picky about these things, and can fail on things that other tools let through. XJC对这些事情非常挑剔,并且在其他工具可以通过的事情上失败。

Rather than picking through XJC's errors, I find it easier to run the schema through the AlphaWorks Schema Quality Checker first. 我发现首先通过AlphaWorks架构质量检查器更容易运行架构,而不是挑选XJC的错误。 This gives a nice, human-readable (well, developer-readable, anyway) output of what's wrong. 这给出了一个很好的,人类可读的(好的,开发人员可读的,无论如何)错误输出。 If it gets through that OK, you'll stand a much better chance of it getting through XJC too. 如果它通过那个好的,你将有更好的机会通过XJC。

另一种选择是删除-p选项,以便在不同的包中生成类

I experienced same issue when generating objects from .wsdl using cxf. 使用cxf从.wsdl生成对象时遇到了同样的问题。 Resolution for me is to use -autoNameResolution as error message suggests. 我的解决方案是使用-autoNameResolution作为错误消息建议。 Maven configuration : Maven配置:

         <wsdlOption>
                            <wsdl>${basedir}/test.wsdl</wsdl>
                            <extraargs>
                                <extraarg>-b</extraarg>     
                            <extraarg>http://www.w3.org/2001/XMLSchema.xsd</extraarg>
                                <extraarg>-autoNameResolution</extraarg>
                            </extraargs>
                            <packagenames>
                                <packagename>test.wsdl</packagename>
                            </packagenames>
                        </wsdlOption>

I tried following and it worked for me: 我试过以下,它对我有用:

<jxb:bindings schemaLocation="ClaimActivity-ACORD.xsd">
    <jxb:schemaBindings>
        <jxb:package name="x.x.x.x" />
    </jxb:schemaBindings>
    <jxb:bindings node="//xsd:complexType[@name='ConstructionType']">
        <jxb:class name="AbstractConstructionType" />
    </jxb:bindings>
    <jxb:bindings node="//xsd:complexType[@name='ItemDefinitionType']">
        <jxb:class name="AbstractItemDefinitionType" />
    </jxb:bindings>
    <jxb:bindings node="//xsd:complexType[@name='LocationType']">
        <jxb:class name="AbstractLocationType" />
    </jxb:bindings>
    <jxb:bindings node="//xsd:complexType[@name='TaxFeeType']">
        <jxb:class name="AbstractTaxFeeType" />
    </jxb:bindings>
    <jxb:bindings node="//xsd:complexType[@name='DeductibleType']">
        <jxb:class name="AbstractDeductibleType" />
    </jxb:bindings>
    <jxb:bindings node="//xsd:complexType[@name='RegistrationType']">
        <jxb:class name="AbstractRegistrationType" />
    </jxb:bindings>
</jxb:bindings>

I came across the same error and removed <generatePackage></generatePackage> entirely. 我遇到了同样的错误并完全删除了<generatePackage></generatePackage> This resolved my problem. 这解决了我的问题。

You can use xjc which comes with JDK1.6. 您可以使用JDK1.6附带的xjc。 Also you can try XML to Java, refer this article . 您也可以尝试XML到Java,请参阅本文

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM