我有一个wsdl定义了一个模式:
<xsd:schema elementFormDefault="unqualified"
targetNamespace="http://www.xpto.com/xpto">
Run Code Online (Sandbox Code Playgroud)
和元素:
<xsd:element name="insertResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="sys_id"
type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="table"
type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="display_name"
type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="display_value"
type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="status"
type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="status_message"
type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="error_message"
type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Run Code Online (Sandbox Code Playgroud)
但是当我执行操作并获得响应时,SoapUI说它无效:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<insertResponse xmlns="http://www.xpto.com/xpto">
<sys_id>something</sys_id>
<table>something</table>
<display_name>number</display_name>
<display_value>something</display_value>
<status>something</status>
</insertResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)
SoapUI消息(包含易读性的行):
line 4: Expected element 'sys_id' instead of
'sys_id@http://www.xpto.com/xpto' here in element
insertResponse@http://www.xpto.com/xpto
Run Code Online (Sandbox Code Playgroud)
如果我将WSDL更改为包含elementFormDefault="qualified",则在模式中,相同的响应是有效的.
为什么没有这个响应无效elementFormDefault="qualified"以及正确的方法是什么?
此外,针对此WSDL生成的代码也不喜欢响应,但失败的是:
Unmarshalling Error: unexpected element
(uri:\\"http://www.xpto.com/xpto\\", local:\\"sys_id\\"). Expected
elements are <{}table>,<{}display_value>,<{}display_name>,
<{}error_message>,<{}sys_id>,<{}status_message>,<{}status>
Run Code Online (Sandbox Code Playgroud)
(再次,线条包装易读.)
使用apache-cxf.
在明确回答您的问题之前,似乎需要一些背景信息.
在XSD中,在复杂类型定义中声明的元素被称为该类型的本地元素.(另一种方法是独立地声明它们作为顶级元素;然后它们是全局或顶级的.不巧的是,顶级元素是那些声明位于模式文档顶层的元素,即那些是儿童XSD:模式.)
在XSD架构中声明的每个元素都有一个由命名空间名称和本地名称组成的名称.与XML名称一样,名称空间名称可以为null.当元素的名称具有非空名称空间名称时,它被称为名称空间限定; 相反,当命名空间名称为null时,元素的名称是不合格的.
顶级元素声明从封闭的xsd:schema元素的targetNamespace属性中获取其命名空间.另一方面,局部元素声明提出了一个设计问题:它们是否进入目标命名空间(即它们的名称是否应该是名称空间限定的)?或者他们应该有不合格的名字?
在XSD用户社区中有两种思想流派,负责的工作组中有两种思想流派.有些人认为在命名空间foo的模式文档中声明的任何元素都应该在命名空间foo中 - 毕竟,命名空间的一个功能是告诉你元素的来源,这是寻找文档的第一步.其他人认为本地元素依赖于它们的包含类型,就像属性一样 - 本地属性具有不合格的名称.双方都同意的一点是,其他人都很疯狂,没有一个有两个脑细胞可以相互摩擦的人真的可以相信事情应该那样.
局部元素声明的form属性用于控制所讨论的本地元素是否具有限定名称或非限定名称; 不出所料,它可以采取的两个值是qualified和unqualified.在将elementFormDefault上属性XSD:模式元素用于指定这些值应为当前模式文档中的默认值; 它的值默认为unqualified,但明确指定它几乎总是好的做法,否则一些读者会感到困惑.
有了这些背景信息,现在可以回答你的问题: 为什么没有这个回复无效,elementFormDefault="qualified"以及正确的做法是什么?
在架构中声明的insertResponse元素是顶级的,具有扩展名称(http://www.xpto.com/xpto,insertResponse) - 有时扩展名称以{ http://www.xpto]的形式编写.com/xpto } insertResponse,显然有时(如错误信息所示)格式为insertResponse @ http://www.xpto.com/xpto.
当架构文档未指定时elementFormDefault = "qualified",本地元素名称的形式默认为unqualified.这意味着'sys_id','table','display_name'和其他本地元素的扩展名称都具有null命名空间部分,因此它们的扩展名称为{} sys_id,{} table,{} display_name等.但是你展示的文件有形式
<insertResponse xmlns="http://www.xpto.com/xpto">
<sys_id>something</sys_id>
<table>something</table>
<display_name>number</display_name>
...
Run Code Online (Sandbox Code Playgroud)
insertResponse上的默认名称空间声明确保第一个子元素中以"sys_id"形式给出的名称扩展为{ http://www.xpto.com/xpto } sys_id,对于其他子项也是如此.在几乎所有XML技术中匹配扩展名称的基本规则是像{ http://www.xpto.com/xpto } 这样的显式命名空间名称与空命名空间名称{}不匹配.因此,元素名称{ http://www.xpto.com/xpto } sys_id与名为{} sys_id的元素的元素声明不匹配.在实例中找不到模式所需的元素,并且在实例中找到一个元素,该元素在声明中不匹配任何内容.所以insertResponse元素无效.
指定模式文档时elementFormDefault="qualified",本地元素sys_id等是名称空间限定的.因此,在实例文档中找到的扩展名称和与模式中的声明关联的扩展名称都是相同的,即{ http://www.xpto.com/xpto } sys_id.一切都很好,文档是有效的,生活是好的,或者至少与使用SOAP时一样好.
底线:响应消息的创建者和模式的创建者目前尚未就响应应该是什么样子达成一致.在做正确的做法是对他们俩的理解命名空间限定在XML和XSD中是如何工作的,以及何种形式的答复应采取一致.
祝好运.
| 归档时间: |
|
| 查看次数: |
5624 次 |
| 最近记录: |