问题
I have a wsdl that imports a schema I am trying to resolve xjc naming multiple nested MyElementName classes with the same name - which doesn't compile I have created this binding file below but it gives the error:
parsing a schema...
compiling a schema...
Exception in thread "main" java.lang.IllegalArgumentException: Illegal class inheritance loop.
Outer class MyElementName1 may not subclass from inner class: MyElementName1
at com.sun.codemodel.internal.JDefinedClass._extends(JDefinedClass.java:257)
at com.sun.tools.internal.xjc.generator.bean.ImplStructureStrategy$1._extends(ImplStructureStrategy.java:104)
at com.sun.tools.internal.xjc.generator.bean.BeanGenerator.<init>(BeanGenerator.java:197)
at com.sun.tools.internal.xjc.generator.bean.BeanGenerator.generate(BeanGenerator.java:151)
at com.sun.tools.internal.xjc.model.Model.generateCode(Model.java:275)
at com.sun.tools.internal.xjc.Driver.run(Driver.java:342)
at com.sun.tools.internal.xjc.Driver.run(Driver.java:184)
at com.sun.tools.internal.xjc.Driver._main(Driver.java:107)
at com.sun.tools.internal.xjc.Driver.access$000(Driver.java:64)
at com.sun.tools.internal.xjc.Driver$1.run(Driver.java:87)
I I remove the first binding for MyElementName1 it works correctly but only names 1 of the classes, I want to change both names, how do I change the binding file so that it will properly name both old nested classes to two unique names I have picked below. I want to do this because I have other mappings with 4 nested classes with the same name so being able to name each class would be needed to tackle the more nested problem areas
<jaxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:bindings schemaLocation="MYWSDL.wsdl">
<jaxb:bindings node="//xsd:element[@name='AAAA']//xsd:complexType//xsd:sequence/xsd:element[@name='BBB']//xsd:complexType/xsd:sequence//xsd:element[@name='MyElementName']">
<jaxb:class name="MyElementName1"/>
</jaxb:bindings>
<jaxb:bindings node="//xsd:element[@name='AAAA']//xsd:sequence/xsd:element[@name='BBB']//xsd:element[@name='MyElementName']//xsd:sequence/xsd:element[@name='CCC']//xsd:sequence/xsd:element[@name='MyElementName']/xsd:complexType">
<jaxb:class name="MyElementName2"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
here is xsd (names of fields changed but rest same)
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element minOccurs="0" name="AAA">
<xsd:complexType>
<xsd:element minOccurs="0" name="BBB">
<xsd:complexType>
<xsd:element name="MyElementName">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="CCC">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="MyElementName">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="FromDate" />
<xsd:element ref="ThruDate" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="DDD">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="DueDate" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="0" ref="YYYY" />
<xsd:element minOccurs="0" ref="ZZZZ" />
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:complexType>
</xsd:element>
</xsd:complexType>
</xsd:element>
</xsd:schema>
the field MyElementName2 is ok, that gets built into the java file if I try binding below, its just the first one that jaxb is mapping to the multiple children - including the one that is mapped with MyElementName2. XPath always maps to one node so maybe its a jaxb option, as it seems to be expanding the input
here is the alternative binding that results in its error below
<jaxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:bindings schemaLocation="MYWSDL.wsdl">
<jaxb:bindings node="//xsd:element[@name='AAA']//xsd:sequence/xsd:element[@name='BBB']//xsd:element[@name='MyElementName']">
<jaxb:class name="MyElementName1"/>
</jaxb:bindings>
<jaxb:bindings node="//xsd:element[@name='AAA']//xsd:sequence/xsd:element[@name='BBB']//xsd:element[@name='Billing']//xsd:sequence/xsd:element[@name='CCC']//xsd:sequence/xsd:element[@name='MyElementName']/xsd:complexType">
<jaxb:class name="MyElementName2"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
error:
parsing a schema...
[ERROR] XPath evaluation of "//xsd:element[@name='AAA']//xsd:sequence/xsd:element[@name='BBB']//xsd:element[@name='MyElementName']" results in too many target nodes
Failed to parse a schema.
回答1:
JAXB generates one class per one complex type, so I believe you should bind your custom class name to xs:complexType rather than xs:element. Your first XPath refers to the xs:element and I think JAXB does not know how to bind a class to it. Try this binding:
<jaxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:bindings schemaLocation="MYWSDL.wsdl">
<jaxb:bindings node="//xsd:element[@name='AAAA']//xsd:complexType//xsd:sequence/xsd:element[@name='BBB']//xsd:complexType/xsd:sequence//xsd:element[@name='MyElementName']/xs:complexType">
<jaxb:class name="MyElementName1"/>
</jaxb:bindings>
<jaxb:bindings node="//xsd:element[@name='AAAA']//xsd:sequence/xsd:element[@name='BBB']//xsd:element[@name='MyElementName']//xsd:sequence/xsd:element[@name='CCC']//xsd:sequence/xsd:element[@name='MyElementName']/xsd:complexType">
<jaxb:class name="MyElementName2"/>
</jaxb:bindings>
</jaxb:bindings>
Personally, I prefer using JAXB to XMLBeans. You should be careful with the latter, because when compiling a deeply nested schema it may generate a structure of nested classes impossible to compile due to filename length limitations (usually 255 characters).
回答2:
Your XPath:
//xsd:element[@name='AAA']
//xsd:sequence/xsd:element[@name='BBB']
//xsd:element[@name='MyElementName']
Seems to refer to both of your MyElementName
elements since they're both under BBB
. Try to get rid of //
.
//xsd:element[@name='AAA']
/xsd:complexType
/xsd:sequence
/xsd:element[@name='BBB']
/xsd:complexType
/xsd:sequence
/xsd:element[@name='MyElementName']
I think this is the right direction you go. You have to customize your anonymous inner complex types.
来源:https://stackoverflow.com/questions/25894994/how-to-rename-nested-classes-in-jaxb-xjc