JAXBを使用してXMLバインディングクラスを生成します。
スキーマは一連のレガシーXMLファイルに基づいており、次のスニペットが含まれています。
<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>
「値」属性はxs:string
の「値」プロパティと競合し、コード生成は次のエラーで失敗します。
com.Sun.istack.SAXParseException2: Property "Value" is already defined. Use <jaxb:property> to resolve this conflict.
答えは、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>
_
XPath式はノードを見つけて名前を変更するため、名前の競合を回避できます。
このバインディングXMLファイルを使用すると、生成されたJavaクラスは、目的のgetValueAttribute()
(およびgetValue()
)を持つことになります。
JAXBバインディングファイルの作成/変更を避け、XSDに注釈を付けたくない場合は、属性の定義にjxb:property注釈を追加できます。例:
<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>
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">
Xxxx.xjbファイルが次のように重複した属性名「値」に対して作成されたら(重複はJAXBによって提供されるデフォルトの「値」です)、XJCコマンドを実行して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>
Eclipse(Helios SR1とJuno SR1の両方を試しました)およびCXF 2.6.3でソリューションを使用する際に問題が発生しました。解決策は、開通が言ったことに似ていました。つまり、Eclipseの新規> Webサービスウィザードは、wsdlをfoldre WebContent/wsdlにコピーします。自分でwsdlとバインディングファイルを配置する必要がありました。そうでない場合、バインディングファイルは「このコンパイルの一部ではありません」というエラーを出しました。
WSDLでインラインスキーマを使用することはできませんでしたが、回答1のように外部スキーマで動作しました。
CXFサーブレットエンドポイントの構成オプションを使用しています。私のWSDLには次のものがあります:
<wsdl:port binding="axis2:ConverterSOAP12Binding" name="ConverterSOAP12port_http">
<soap12:address location="http://localhost/Converter/services/Converter"/>
</wsdl:port>
ウィザードはこれをweb.xmlに生成し、正常に機能します。
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
しかし、これを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>
次のように、アドレスを完全なURLに変更する必要がありました。
address="http://localhost:8080/Converter/services/Converter">
このバインディングはどれもうまくいきませんでした、私はこのエラーを受け取りました:
[ERROR] La evaluación de XPath de ".//xs:attribute[@name='Value']" produce un nodo de destino vacío
それは空のターゲットノードを生成しました...その後、私は(30分の失望の後)私のバインディングが要素の代わりにcomplexTypeを目指していることに気付きました。答えは私のxsdファイルにありました。
ありがとうございました
他の回答に記載されているこのバインディングファイルは、CXF 3.0.0では機能しませんでした。 jaxb名前空間には要素 "bindings"があり、名前空間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>
私の場合、スキーマはすでにWSDL内にあるため、schemaLocation属性を指定する必要はありませんでした。
また、コマンドラインおよびプラグインでパラメーター-XautoNameResolutionを使用して、クラスの名前を気にしない場合にjxcが名前を解決できるようにすることもできます。