0

我有一个 wsdl,它定义了一个模式:

<xsd:schema elementFormDefault="unqualified" 
            targetNamespace="http://www.xpto.com/xpto">

和元素:

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

但是当我执行操作并得到响应时,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>

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

如果我将 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> 

(再次,为了便于阅读,换行。)

使用 apache-cxf。

4

1 回答 1

6

在清楚地回答您的问题之前,似乎需要一些背景信息。

在 XSD 中,在复杂类型定义中声明的元素被称为是该类型的本地元素。(另一种方法是将它们独立声明为顶级元素;然后它们是globaltop-level。并非巧合的是,顶级元素是那些声明位于模式文档顶层的元素,即那些xsd:schema的孩子。)

XSD 模式中声明的每个元素都有一个名称,该名称由名称空间名称和本地名称组成。通常与 XML 名称一样,名称空间名称可能为空。当元素的名称具有非空命名空间名称时,称其为命名空间限定的;相反,当命名空间名称为 null 时,元素的名称是unqualified

顶级元素声明从封闭xsd:schema元素上的targetNamespace属性获取其命名空间。另一方面,局部元素声明提出了一个设计问题:它们是否进入目标命名空间(即它们的名称是否应该是命名空间限定的)?或者他们应该有不合格的名字?

XSD 用户社区对此有两种思想流派,负责的 WG 也有两种思想流派。有些人认为在命名空间 foo 的模式文档中声明的任何元素应该在命名空间foo中——毕竟,命名空间的功能之一是告诉您元素来自哪里,这是查找文档的第一步。其他人认为本地元素依赖于它们的包含类型,就像属性一样——并且本地属性具有非限定名称。双方一致同意的一件事是,其他人都疯了,没有两个脑细胞相互摩擦的人会真正相信事情应该是这样的。

本地元素声明中的form属性用于控制所讨论的本地元素是否具有限定名称或非限定名称;不出所料,它可以采用的两个值是qualifiedunqualifiedxsd:schema元素上的elementFormDefault属性用于指定哪些值应该是当前模式文档中的默认值;它的值默认为,但明确指定它几乎总是好的做法,否则一些读者会感到困惑。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”和其他本地元素的扩展名称都有一个空命名空间部分,因此它们的扩展名称是 {}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>
...

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 等是命名空间限定的。所以在实例文档中找到的扩展名和schema中声明关联的扩展名都是一样的,即{ http://www.xpto.com/xpto}sys_id。一切都很好,文档是有效的,生活也很好,或者至少和使用 SOAP 时一样好。

底线:响应消息的创建者和模式的创建者目前在响应应该是什么样子上没有达成一致。正确的做法是让他们都了解名称空间限定在 XML 和 XSD 中是如何工作的,并就响应应该采用的形式达成一致。

祝你好运。

于 2013-06-27T14:09:02.987 回答