使用 JAXB 从 XMLSchema.xsd 生成 Java 类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2409278/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Generating Java classes out of XMLSchema.xsd using JAXB
提问by Christian Schulz
I'm using jaxb to generate java classes out of a xml schema. The schema imports XMLSchema.xsd and its content is used as an element in the document.
我正在使用 jaxb 从 xml 模式中生成 java 类。架构导入 XMLSchema.xsd,其内容用作文档中的元素。
If I remove the import and the reference to "xsd:schema" respectively then the binding compiler generates successfully the classes. 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!
如果我分别删除导入和对“xsd:schema”的引用,则绑定编译器会成功生成类。如果我不这样做,它将产生以下错误,如果我尝试仅从 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.
回答by skaffman
It looks like your schema is broken. XJC is extremelypicky 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 Checkerfirst. 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.
我发现首先通过AlphaWorks Schema Quality Checker运行模式比挑选 XJC 的错误更容易。这给出了一个很好的、人类可读的(好吧,开发人员可读的)输出错误。如果它通过了,那么你也将有更大的机会通过 XJC。
回答by Sunil
You can use xjc which comes with JDK1.6. Also you can try XML to Java, refer this article.
您可以使用 JDK1.6 附带的 xjc。你也可以尝试从 XML 到 Java,参考这篇文章。
回答by Keith Layne
You can successfully get JAXB to generate code for the XML Schema xsd by (at least) two methods. The problem you are experiencing stems from the fact that some schema types and elements share the same names.
您可以通过(至少)两种方法成功地让 JAXB 为 XML Schema xsd 生成代码。您遇到的问题源于某些架构类型和元素共享相同名称的事实。
The first option avoids name conflicts by applying one or more XML name transformations to the generated class names. Here is an example of an external binding file that will do this:
第一个选项通过对生成的类名应用一个或多个 XML 名称转换来避免名称冲突。这是执行此操作的外部绑定文件的示例:
<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. In fact, all but one of the problem classes has the property abstract="true"
set in the corresponding schema type. Therefore it makes sense to me to prepend the class name with "Abstract", i.e. AbstractElement
. The remaining Attribute
class is not abstract, but the xs:element
named attribute
generates an extension class with an empty body. Therefore I called it BaseAttribute
. Here is the external binding definition I used:
第二种方法使用 xjc 输出建议的类自定义。事实上,除了一个问题类之外,所有的类都abstract="true"
在相应的模式类型中设置了属性。因此,在类名前加上“抽象”对我来说是有意义的,即AbstractElement
. 剩下的Attribute
类不是抽象类,但xs:element
命名attribute
生成了一个空体的扩展类。因此我称之为BaseAttribute
。这是我使用的外部绑定定义:
<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. The answers to this questiondescribe how.
我还建议对 XMLSchema.xsd 使用单独的编译并将其保存在 jar 文件中以备后用,以防在编译另一个模式时再次出现此问题。这个问题的答案描述了如何。
回答by tomasb
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 的本地副本并手动修复重复项。
EditFound 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.
祝你好运,希望这会有帮助。
回答by blue-sky
I experienced same issue when generating objects from .wsdl using cxf. Resolution for me is to use -autoNameResolution as error message suggests. Maven configuration :
我在使用 cxf 从 .wsdl 生成对象时遇到了同样的问题。我的解决方案是使用 -autoNameResolution 作为错误消息建议。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>
回答by Dharamendra Prajapati
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>
回答by Christos
Another option would be to remove the -p
option so the classes are generated in different packages
另一种选择是删除该-p
选项,以便在不同的包中生成类
回答by Hamid Mohayeji
I came across the same error and removed <generatePackage></generatePackage>
entirely. This resolved my problem.
我遇到了同样的错误并<generatePackage></generatePackage>
完全删除了。这解决了我的问题。