web-dev-qa-db-ja.com

JAXB-プロパティ「値」はすでに定義されています。 <jaxb:property>を使用してこの競合を解決します

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 &lt;jaxb:property> to resolve this conflict. 
59
brasskazoo

答えは、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())を持つことになります。

62
brasskazoo

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">
20
Gary

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

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">
1
user1787681

このバインディングはどれもうまくいきませんでした、私はこのエラーを受け取りました:

[ERROR] La evaluación de XPath de ".//xs:attribute[@name='Value']" produce un nodo de destino vacío

それは空のターゲットノードを生成しました...その後、私は(30分の失望の後)私のバインディングが要素の代わりにcomplexTypeを目指していることに気付きました。答えは私のxsdファイルにありました。

ありがとうございました

1

他の回答に記載されているこのバインディングファイルは、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が名前を解決できるようにすることもできます。

0