2010-03-09 1 views
18

Ich verwende Jaxb, um Java-Klassen aus einem XML-Schema zu generieren. Das Schema importiert XMLSchema.xsd und sein Inhalt wird als Element im Dokument verwendet.Generieren von Java-Klassen aus XMLSchema.xsd mit JAXB

Wenn ich den Import und den Verweis auf "xsd: schema" entfernen, generiert der Bindungscompiler erfolgreich die Klassen. Wenn ich das nicht tue, würde es die folgenden Fehler erzeugen, die die gleichen sind, wenn ich versuchen würde, Java-Klassen nur aus dem XMLSchema.xsd zu generieren!

> 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. 

Antwort

4

Es sieht aus wie Ihr Schema ist gebrochen. XJC ist extrem wählerisch über diese Dinge, und kann auf Dinge, die andere Werkzeuge durchlassen fehlschlagen.

Anstatt durch XJC-Fehler zu wählen, finde ich es einfacher, das Schema über die AlphaWorks Schema Quality Checker zuerst auszuführen. Dies ergibt eine nette, menschenlesbare (na ja, Entwickler lesbar, jedenfalls) Ausgabe von was falsch ist. Wenn es soweit kommt, haben Sie eine viel bessere Chance, dass es auch durch XJC kommt.

+1

Danke für den Hinweis auf SQC, obwohl es die oben genannten Probleme nicht erkennt. – david

+0

Der Link scheint kaputt zu sein. Können Sie bitte ein neues liefern? –

+0

Ich verwendete https://www.wsdl-analyzer.com –

-1

Sie können xjc verwenden, das mit JDK1.6 geliefert wird. Sie können auch XML nach Java ausprobieren, siehe this article.

+0

Das OP bereits verwendet xjc –

9

Sie können JAXB erfolgreich dazu bringen, Code für das XML-Schema xsd mit (mindestens) zwei Methoden zu generieren. Das Problem besteht darin, dass einige Schematypen und Elemente dieselben Namen haben.

Die erste Option vermeidet Namenskonflikte, indem eine oder mehrere XML-Namensumwandlungen auf die generierten Klassennamen angewendet werden. Hier ist ein Beispiel für eine externe Bindungsdatei, die dies tun wird:

<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> 

Dieser Ansatz funktioniert (Sie könnten auch andere Transformationen anwenden, die genauso gut funktionieren würden, aber ich habe diese Technik immer und immer wieder in der Dokumentation zu sehen) aber ich denke, es erzeugt hässliche Ergebnisse. Zum Beispiel gibt es eine generierte Klasse mit dem Namen ElementElement.


Der zweite Ansatz verwendet Klassenanpassung, wie von der Ausgabe von xjc vorgeschlagen. In der Tat hat alle außer einer der Problemklassen die Eigenschaft abstract="true" in dem entsprechenden Schematyp festgelegt. Daher macht es für mich Sinn, den Klassennamen mit "Abstract" voranzutreiben, d. H. AbstractElement. Die verbleibende Attribute Klasse ist nicht abstrakt, aber die xs:element mit dem Namen generiert eine Erweiterungsklasse mit einem leeren Körper. Deshalb nannte ich es BaseAttribute. Hier ist die externe Datenflußdefinition I verwendet:

<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> 

Dies gibt klarere generierten Klassennamen meiner Meinung nach, und kompiliert erfolgreich das Schema.


Ich würde auch mit getrennter Sammlung für XMLSchema.xsd empfehlen und es in einer JAR-Datei zur späteren Verwendung bei Beibehaltung dieses Thema wieder aufkam, während ein anderes Schema zu kompilieren. Die Antworten auf this question beschreiben wie.

+0

vor ähnlichen Problem. Aber ich habe etwa 50 solcher Variablen jede alternative Lösung? – wib

14

Auch solche Dinge zu bekämpfen, ist für mich die Groß- und Kleinschreibung und der gleiche Name für Element und Attribut (manchmal durch Vererbung).Für das zweite Problem bin ich mit externer Einbindemappe, die so etwas wie dies enthält:

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

für Groß- und Klein Fragen können Sie xjc Argument -XautoNameResolution, Maven Version ist <args><arg>-B-XautoNameResolution</arg></args> verwenden, aber das funktioniert nicht Für Wrapper-Elemente, also für diese müssen Sie Jaxb Anpassungen wie oben erwähnt, schreiben ... und wenn Sie Pech haben wie ich :) müssen Sie möglicherweise eine lokale Kopie eines Xsd und Fix Duplikationen manuell.

bearbeiten eine andere Lösung für das Problem Groß- und Klein gefunden, in dem Namen des Elements Umbenennung ist nicht genug:

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

Viel Glück, hoffe, das hilft.

+7

-XautoNameResolution löste es für mich :-D –

2

Ich habe das gleiche Problem beim Generieren von Objekten aus .wsdl mit CXF. Lösung für mich ist die Verwendung von -autoResolution als Fehlermeldung vorgeschlagen. Maven-Konfiguration:

  <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> 
0

Ich habe versucht, folgende und es funktionierte für mich:

<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> 

1

Eine andere Möglichkeit wäre die Option -p zu entfernen, so dass die Klassen in verschiedenen Paketen erzeugt werden