2013-06-27 116 views
0

我已經定義與模式的WSDL:WSDL SOAP響應驗證

<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 
'[email protected]://www.xpto.com/xpto' here in element 
[email protected]://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。

回答

6

在您的問題可以清楚回答之前,似乎需要一些背景信息。

在XSD中,在複雜類型定義中聲明的元素被稱爲本地到該類型。 (另一種方法是獨立地聲明它們,作爲頂層元素;然後它們全球頂層並非巧合的是頂級元素是那些聲明是在模式文檔的頂層,即那些是xsd的兒童:模式。)

在XSD架構中聲明的每個元素都有一個由名稱空間名稱和本地名稱組成的名稱。與通常的XML名稱一樣,名稱空間名稱可能爲空。當元素名稱具有非空名稱空間名稱時,它被稱爲命名空間限定;當名稱空間名稱爲空時,相反,該元素的名稱是不合格

頂級元素聲明把他們的名字空間從的targetNamespace屬性上封閉XSD:架構元素。另一方面,本地元素聲明提出了一個設計問題:它們是否進入目標名稱空間(即它們的名稱是否應該是名稱空間限定的)?還是應該有不合格的名字?

在XSD用戶社區中,有兩種學派的思想,負責的工作組中有兩種思想流派。有些人認爲,一個架構文檔中聲明的命名空間任何元素應該在命名空間 - 畢竟,一個命名空間的功能之一是告訴你在哪裏元素的來源,這是對的第一步查找文件。其他人則認爲,本地元素的屬性取決於它們的包含類型,而本地屬性的名稱是不合格的。雙方都同意的一點是,其他人都瘋了,沒有兩個腦細胞一起搓揉的人實際上會認爲事情應該是這樣。

表格本地元素聲明的屬性用於控制本地元素是否具有限定名稱或非限定名稱;不出所料,它可以採取的兩個值是qualifiedunqualified上的elementFormDefault屬性xsd:schema元素用於指定哪些值應爲當前模式文檔中的默認值;它的值默認爲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等是名稱空間限定的。因此,在實例文檔中找到的展開名稱以及與架構中的聲明關聯的展開名稱都是相同的,即{http://www.xpto.com/xpto} sys_id。一切都很好,文檔是有效的,而且生活是美好的,或者至少與使用SOAP時一樣好。

底線:響應消息的創建者和模式的創建者目前對於響應應該是什麼樣子並不一致。 正確的方法是爲了讓他們理解XML和XSD中的名稱空間限定是如何工作的,並且同意應該採取什麼形式的響應。

祝你好運。

+0

令人敬畏的答案,我想我明白了。謝謝 – GriffinHeart