Utilisation de JAXB pour générer des classes de liaison XML.
Le schéma est basé sur un ensemble de fichiers XML hérités et comprend cet extrait de code:
<xs:complexType name="MetaType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="Name" />
<xs:attribute type="xs:string" name="Scheme" />
<xs:attribute type="xs:string" name="Value" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
L'attribut 'Valeur' est en conflit avec la propriété 'valeur' de xs:string
et la génération de code échoue avec l'erreur suivante:
com.Sun.istack.SAXParseException2: Property "Value" is already defined. Use <jaxb:property> to resolve this conflict.
La réponse réside dans l'utilisation des liaisons JAXB (site-template.xjb
):
<bindings xmlns="http://Java.Sun.com/xml/ns/jaxb"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.1">
<bindings schemaLocation="site-template.xsd" version="1.0">
<!-- Customise the package name -->
<schemaBindings>
<package name="com.example.schema"/>
</schemaBindings>
<!-- rename the value element -->
<bindings node="//xs:complexType[@name='MetaType']">
<bindings node=".//xs:attribute[@name='Value']">
<property name="ValueAttribute"/>
</bindings>
</bindings>
</bindings>
</bindings>
Les expressions XPath localisent les nœuds et les renomment, évitant ainsi le conflit de dénomination.
En utilisant ce fichier XML de liaisons, la classe Java générée finit par avoir le getValueAttribute()
souhaité (ainsi que le getValue()
).
Si vous souhaitez éviter de créer/modifier un fichier de liaisons JAXB et que l'annotation de votre fichier XSD ne vous gêne pas, vous pouvez ajouter le jxb: property annotation à la définition de votre attribut, par exemple:
<xs:complexType name="MetaType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="Name" />
<xs:attribute type="xs:string" name="Scheme" />
<xs:attribute type="xs:string" name="Value">
<!-- rename property generated by JAXB (avoiding "Value" name conflict) -->
<xs:annotation>
<xs:appinfo>
<jxb:property name="valueAttribute"/>
</xs:appinfo>
</xs:annotation>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
avec des ajouts appropriés à la balise xs: schema:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://Java.Sun.com/xml/ns/jaxb"
jxb:version="2.1">
Une fois que le fichier xxxx.xjb est créé pour le nom d'attribut en double "valeur" (la valeur par défaut fournie par JAXB est dupliquée), exécutez la commande XJC pour créer des objets JAXB.
xjc -p "com.track.doc" -d "C:\JAXBDocuments\prasam\Desktop\JAXB_me\DealerTrace" appSamp.xsd -b xxxx.xjb
appSmp.xsd : -
<xsd:complexType name="range">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="value" type="xsd:string"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
xxxx.xjb : -
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://Java.Sun.com/xml/ns/jaxb"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.1">
<bindings schemaLocation="appSmp.xsd" version="1.0">
<schemaBindings>
<package name="com.track.doc"/>
</schemaBindings>
<bindings node="//xs:complexType[@name='range']">
<bindings node=".//xs:attribute[@name='value']">
<property name="valueAttribute"/>
</bindings>
</bindings>
</bindings>
</bindings>
J'ai eu un problème en utilisant la solution avec Eclipse (essayé à la fois Helios SR1 et Juno SR1) et CXF 2.6.3. La solution était similaire à celle de Kaitsu. En particulier, l'assistant Nouveau> Service Web d'Eclipse copie le fichier WSDL dans le dossier WebContent/WSDL. Je devais y placer moi-même le fichier wsdl et le fichier de liaison. Sinon, le fichier de liaison a donné l'erreur "ne fait pas partie de cette compilation".
Je n'ai pas pu utiliser de schéma en ligne dans le WSDL, mais cela fonctionnait avec un schéma externe comme dans la réponse n ° 1.
J'utilise l'option de configuration de point final CXF Servlet. Dans mon WSDL j'ai:
<wsdl:port binding="axis2:ConverterSOAP12Binding" name="ConverterSOAP12port_http">
<soap12:address location="http://localhost/Converter/services/Converter"/>
</wsdl:port>
L'assistant a généré cela dans mon fichier web.xml, ce qui fonctionne bien:
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
Mais cela a mis cela dans cxf-servlet.xml:
<jaxws:endpoint xmlns:tns="http://wtp" id="converterporttype"
implementor="wtp.ConverterPortTypeImpl" wsdlLocation="wsdl/Converter.wsdl"
endpointName="tns:ConverterSOAP12port_http" serviceName="tns:Converter"
address="/ConverterSOAP12port_http">
<jaxws:features>
<bean class="org.Apache.cxf.feature.LoggingFeature" />
</jaxws:features>
</jaxws:endpoint>
Je devais changer l'adresse dans l'URL complète, comme ceci:
address="http://localhost:8080/Converter/services/Converter">
Aucune de ces liaisons ne fonctionnait pour moi, j'ai cette erreur:
[ERROR] La evaluación de XPath de ".//xs:attribute[@name='Value']" produce un nodo de destino vacío
Cela a produit un nœud cible vide ... Puis, j'ai réalisé (après 30 minutes de discussion) que ma liaison visait un complexType au lieu d'un élément. La réponse était dans mon fichier xsd.
Je vous remercie
Ce fichier de liaisons mentionné dans l'autre réponse ne fonctionnait pas pour moi avec CXF 3.0.0 . Notez que l'espace de noms jaxb a un élément "bindings", de même que l'espace de noms jaxws;
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://Java.Sun.com/xml/ns/jaxws"
xmlns:jaxb="http://Java.Sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
wsdlLocation="mesh.wsdl" >
<bindings node="wsdl:definitions/wsdl:types/xs:schema[...">
<jaxb:bindings node="./xs:element[@name='Profiles']">
<jaxb:property name="ProfilesElement"/>
</jaxb:bindings>
</bindings>
</bindings>
Dans mon cas, le schéma se trouvait déjà dans le WSDL, je n'avais donc pas à spécifier l'attribut schemaLocation.
vous pouvez également utiliser le paramètre -XautoNameResolution dans la ligne de commande et également dans le plug-in pour laisser jxc résoudre le nom si vous ne vous souciez pas du nom des classes.