【问题标题】:JAXB - Property "Value" is already defined. Use <jaxb:property> to resolve this conflictJAXB - 属性“值”已定义。使用 <jaxb:property> 解决此冲突
【发布时间】:2011-05-22 14:28:11
【问题描述】:

使用 JAXB 生成 XML 绑定类。

架构基于一组旧的 XML 文件,并包含这个 sn-p:

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

【问题讨论】:

    标签: java xsd jaxb


    【解决方案1】:

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

    【讨论】:

    • 我也遇到了这个问题,这个答案解决了,谢谢!想补充一点,如果你使用 Maven jaxb 插件生成 Java 类,你可以把 xjb 文件和实际的 XSD 文件放在同一个资源目录中。
    • 这个解决方案能以某种方式用于远程 XSD 吗?我得到“不是这个汇编的一部分”。错误。谢谢。
    • 我应该把这个site-template.xjb文件放在哪里?
    • @Andremoniy 将文件放在您喜欢的任何位置,然后将其指定为命令行参数。请参阅@rrayasam 答案中的-b 参数
    • 这里有什么帮助,是对 .xjb 文件绑定到 .xsd 的一些解释
    【解决方案2】:

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

    【讨论】:

    • 这对我来说好多了。接受的答案需要我无法管理的设置。我只是想让它工作!
    • 我认为这个答案更适合作为一个正确的问题答案
    • 嗨。我正在尝试使用它来修复我的 .wsdl 文件,但是 wsdl 定义说它们不允许 jxb:version 在 元素中。我怎样才能在那里注入 jxb 命名空间和版本?
    • 更直接的方法。也为我工作!
    • 感谢它的帮助,-p xxx.xjb 更具挑战性。
    【解决方案3】:

    如下所示,为重复属性名称“value”(重复是 JAXB 提供的默认“value”)创建 xxxx.xjb 文件后,运行 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>
    

    【讨论】:

    • 您好,感谢您的回答。实际上,我遇到了这个问题,所以我找到了这个答案并尝试按照此处提供的步骤操作:我将 appSmp.xsd 和 'xxxx.xjb' 文件与此答案中提供的内容一起放在了一个目录中。更改文件路径并运行以下命令:xjc -p "com.track.doc" -d "path" appSamp.xsd -b xxxx.xjb 仍然出现错误:` [ERROR] schema_reference.4: Failed to read schema document '´path/appSamp.xsd',因为 1) 找不到文档; 2) 文件无法读取; 3) 文档的根元素不是。未知位置`
    【解决方案4】:

    我在使用 Eclipse(尝试了 Helios SR1 和 Juno SR1)和 CXF 2.6.3 的解决方案时遇到了问题。解决方案类似于 Kaitsu 所说的。即 Eclipse 的 New > Web Service 向导将 wsdl 复制到文件夹 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">
    

    【讨论】:

      【解决方案5】:

      这些绑定都不适合我,我收到了这个错误:

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

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

      谢谢

      【讨论】:

        【解决方案6】:

        另一个答案中提到的这个绑定文件不适用于 CXF 3.0.0。 请注意,jaxb 命名空间有一个元素“绑定”,命名空间 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 属性。

        【讨论】:

        • 这是包含jaxb:property 的唯一答案,但我不明白这里的答案与文件的其余部分有何关系。一方面,我在尝试修复的 WSDL 文件中看不到 bindings 标记。
        • 此 XML 位于 .xjb 文件中。这个其他问题有一个例子:stackoverflow.com/questions/23961421
        【解决方案7】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-12-22
          • 2016-01-12
          • 1970-01-01
          • 2013-02-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多