JAXB - 属性“值”已定义。使用 <jaxb:property> 解决此冲突
Posted
技术标签:
【中文标题】JAXB - 属性“值”已定义。使用 <jaxb:property> 解决此冲突【英文标题】:JAXB - Property "Value" is already defined. Use <jaxb:property> to resolve this conflict 【发布时间】: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 <jaxb:property> to resolve this conflict.
【问题讨论】:
【参考方案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 在如下所示,为重复属性名称“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) 文档的根元素不是我在使用 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 文件中。这个其他问题有一个例子:***.com/questions/23961421【参考方案7】:
您也可以在命令行和插件中使用参数 -XautoNameResolution 让 jxc 解析名称,如果您不关心类上的名称。
【讨论】:
以上是关于JAXB - 属性“值”已定义。使用 <jaxb:property> 解决此冲突的主要内容,如果未能解决你的问题,请参考以下文章