JAXB - 属性“值”已定义。使用<jaxb:property>解决此冲突</jaxb:property>

时间:2010-12-09 01:47:44

标签: java xsd jaxb

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

'Value'属性与xs:string的'value'属性冲突,代码生成失败并显示错误:

com.sun.istack.SAXParseException2: Property "Value" is already defined. Use &lt;jaxb:property> to resolve this conflict. 

7 个答案:

答案 0 :(得分:62)

答案在于使用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())。

答案 1 :(得分:18)

如果您想避免创建/更改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">

答案 2 :(得分:7)

在为重复的属性名称&#34;值&#34;创建xxxx.xjb文件之后(重复是默认值&#39;值&#39;由JAXB提供),如下所示,运行XJC命令来创建JAXB对象

xjc -p&#34; com.track.doc&#34; -d&#34; C:\ JAXBDocuments \ prasam \ Desktop \ JAXB_me \ DealerTrace&#34; 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>

答案 3 :(得分:1)

我在使用Eclipse(试过Helios SR1和Juno SR1)和CXF 2.6.3的解决方案时遇到了问题。解决方案类似于Kaitsu所说的。即新的&gt; Eclipse的Web Service向导将wsdl复制到foldre WebContent / wsdl中。我必须自己放置wsdl和绑定文件。否则绑定文件给出“不是此编译的一部分”错误。

我无法在WSDL中使用内联架构,但它确实适用于外部架构,如答案#1。

我正在使用CXF Servlet端点配置选项。在我的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">

答案 4 :(得分:1)

没有任何绑定对我有用,我得到了这个错误:

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

它产生了一个空的目标节点...然后我(在失望了30分钟后)意识到我的绑定目标是用complexType而不是元素。答案在我的xsd文件中。

谢谢

答案 5 :(得分:0)

另一个答案中提到的绑定文件对我来说不适用于CXF 3.0.0。 请注意,jaxb名称空间有一个元素&#34; bindings&#34;命名空间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属性。

答案 6 :(得分:0)

您也可以在命令行中使用参数-XautoNameResolution,也可以在插件中使用jxc解析名称,如果您不打扰类的名称。