SOAP協議規範(一)
SOAP協議規範
1. 簡介
SOAP以XML形式提供了一個簡單、輕量的用於在分散或分佈環境中交換結構化和型別資訊的機制。SOAP本身並沒有定義任何應用程式語義,如程式設計模型或特定語義的實現;實際上它通過提供一個有標準元件的包模型和在模組中編碼資料的機制,定義了一個簡單的表示應用程式語義的機制。這使SOAP能夠被用於從訊息傳遞到RPC的各種系統。
soap包括三個部分
soap封裝(見第4節)結構定義了一個整體框架用來表示訊息中包含什麼內容,誰來處理這些內容以及這些內容是可選的或是必需的。
SOAP編碼規則(見第5節)定義了用以交換應用程式定義的資料型別的例項的一系列機制。
SOAP RPC表示(見第7節)定義了一個用來表示遠端過程呼叫和應答的協定。
雖然這三個部分都作為SOAP的一部分一起描述,但它們在功能上是相交的。特別的,封裝和編碼規則是在不同的名域中定義的,這種模組性的定義方法增加了簡單性在SOAP封裝,SOAP編碼規則和SOAPRPC協定之外,這個規範還定義了兩個協議的繫結,描述了在有或沒有HTTP擴充套件框架[6]的情況下,SOAP訊息如何包含在HTTP訊息[5]中被傳送。
1.1 設計目標
SOAP的主要設計目標是簡單性和可擴充套件性,這意味著傳統的訊息系統和分佈物件系統的某些性質不是SOAP規範的一部分。這些性質包括:
分散式碎片收集
成批傳送訊息
物件引用(要求分散式碎片收集)
啟用機制(要求物件引用)
1.2 符號約定
這篇文章中的關鍵字 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT","SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 和"OPTIONAL"的解釋在RFC-2119 [2]中。 這篇文章中用到的名域字首 "SOAP-ENV" 和"SOAP-ENC"分別與"http://schemas.xmlsoap.org/soap/envelope/"; 和"http://schemas.xmlsoap.org/soap/encoding/";關聯。整篇文件中,名域字首“xsi”被假定為與URI"http://www.w3.org/1999/XMLSchema-instance“(在XMLSchema規範[11]定義)相連。類似的,名域字首”xsd“被假定為與URI"http://www.w3.org/1999/XMLSchema";(在[10]中定義)相連。名域字首”tns“用來表示任意名域。所有其它的名域字首都只是例子。
名域URI的基本形式”some-URI“表示某些依賴於應用程式或上下文的URI[4]。這個規範用擴充套件BNF(在RFC-2616[5] 描述)描述某些結構。
1.3 soap訊息舉例
在這個例子中,GetLastTradePrice SOAP 請求被髮往StockQuote服務。這個請求攜帶一個字串引數和ticker符號,在SOAP應答中返回一個浮點數。XML名域用來區分SOAP標誌符和應用程式特定的標誌符。這個例子說明了在第6節中定義的HTTP繫結。如果SOAP中管理XML負載的規則完全獨立於HTTP是沒有意義的,因為事實上該負載是由HTTP攜帶的。在Appendix A中有更多的例子。
例1 在http請求中嵌入soap訊息
post /stockquote http/1.1
Host:
www.stockquoteserver.com
Content-Type: text/xml;
charset="utf-8"
Content-Length: nnnn
SOAPAction:
"Some-URI"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
SOAP-ENV:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/";>
DIS
下面是一條應答訊息,包括http訊息,soap訊息是其具體內容 :
例2 在http應答中嵌入soap訊息
http/1.1 200 ok
Content-Type: text/xml;
charset="utf-8"
Content-Length:
nnnn
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
SOAP-ENV:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/";/>
34.5
2. soap訊息交換模型
SOAP訊息從傳送方到接收方是單向傳送,但正如上面顯示的,SOAP訊息經常以請求/應答的方式實現。SOAP實現可以通過開發特定網路系統的特性來優化。例如,HTTP繫結(見第6節)使SOAP應答訊息以HTTP應答的方式傳輸,並使用同一個連線返回請求。不管SOAP被繫結到哪個協議,SOAP訊息採用所謂的”訊息路徑“傳送,這使在終節點之外的中間節點可以處理訊息。一個接收SOAP訊息的SOAP應用程式必須按順序執行以下的動作來處理訊息:識別應用程式想要的SOAP訊息的所有部分 (見4.2.2節)檢驗應用程式是否支援第一步中識別的訊息中所有必需部分並處理它。如果不支援,則丟棄訊息(見4.4節)。在不影響處理結果的情況下,處理器可能忽略第一步中識別出的可選部分。如果這個SOAP應用程式不是這個訊息的最終目的地,則在轉發訊息之前刪除第一步中識別出來的所有部分。為了正確處理一條訊息或者訊息的一部分,SOAP處理器需要理解:所用的交換方式(單向,請求/應答,多路傳送等等),這種方式下接收者的任務,RPC機制(如果有的話)的使用(如第7節中所述),資料的表現方法或編碼,還有其它必需的語義。儘管屬性(比如SOAP encodingstyle,見4.1.1節)可以用於描述一個訊息的某些方面,但這個規範並不 強制所有的接收方也必須有同樣的屬性並取同樣的屬性值。舉個例子,某一特定的應用可能知道一個元素表示一條遵循第7節約定的RPC請求,但是另外一些應用可能認為指向該元素的所有訊息都用單向傳輸,而不是類似第7節的請求應答模式。
(譯者注:互動雙方的SOAP訊息並不一定要遵循同樣的格式設定,而只需要以一種雙方可理解的格式交換資訊就可以了)
3. 與xml的關係
所有的SOAP訊息都使用XML形式編碼(更多有關XML的資訊請見[7])一個SOAP應用程式產生的訊息中,所有由SOAP定義的元素和屬性中必須包括正確的名域。SOAP應用程式必須能夠處理它接收到的訊息中的SOAP名域(見4.4節),並且它可以處理沒有SOAP名域的SOAP訊息,就象它們有正確的名域一樣。SOAP定義了兩個名域(更多有關XML名域的資訊請見[8])
soap封裝的名域標誌符是"http://schemas.xmlsoap.org/soap/envelope/";
SOAP的編碼規則的名域標誌符是"http://schemas.xmlsoap.org/soap/encoding/";
SOAP訊息中不能包含文件型別宣告,也不能包括訊息處理指令。[7] SOAP使用"ID"型別"id"屬性來指定一個元素的唯一的標誌符,同時該屬性是區域性的和無需校驗的。SOAP使用"uri-reference"型別的"href"屬性指定對這個值的引用,同時該屬性是區域性的和無需校驗的。這樣就遵從了XML規範[7],XMLSchema規範[11]和XML連線語言規範[9]的風格。除了SOAP mustUnderstand 屬性(見4.2.3節)和SOAPactor屬性(見4.2.2節)之外,一般允許屬性和它們的值出現在XML文件例項或Schema中(兩者效果相同)。也就是說,在DTD或Schema中宣告一個預設值或固定值和在XML文件例項中設定它的值在語義上相同。
4. soap封裝
SOAP訊息是一個XML文件,包括一個必需的SOAP封裝,一個可選的SOAP頭和一個必需的SOAP體。在這篇規範剩餘部分中,提到SOAP訊息時就是指這個XML文件。這一節中定義的元素和屬性的名域標誌符為:
"http://schemas.xmlsoap.org/soap/envelope/"; 。一個SOAP訊息包括以下部分:1.在表示這個訊息的XML文件中,封裝是頂層元素。2.應用SOAP交換資訊的各方是分散的且沒有預先協定,SOAP頭提供了向SOAP訊息中新增關於這條SOAP訊息的某些要素(feature)的機制。SOAP定義了少量的屬性用來表明這項要素(feature)是否可選以及由誰來處理。(見4.2節)3.SOAP體是包含訊息的最終接收者想要的資訊的容器(見4.3節)。SOAP為SOAP體定義了一個Fault元素用來報告錯誤資訊。語法規則如下所示:
封裝
元素名是 "envelope"
在SOAP訊息中必須出現。
可以包含名域宣告和附加屬性。如果包含附加屬性,這些屬性必須限定名域。類似的,"Envelope"可以包含附加子元素,這些也必須限定名域且跟在SOAP體元素之後。
SOAP頭 (見4.2節)
元素名是"header"
在SOAP訊息中可能出現。如果出現的話,必須是SOAP封裝元素的第一個直接子元素。
SOAP頭可以包含多個條目,每個都是SOAP頭元素的直接子元素。所有SOAP頭的直接子元素都必須限定名域。
SOAP體 (見4.3節)
元素名是"body"
在SOAP訊息中必須出現且必須是SOAP封裝元素的直接子元素。它必須直接跟在SOAP頭元素(如果有)之後。否則它必須是SOAP封裝元素的第一個直接子元素。
SOAP體可以包括多個條目,每個條目必須是SOAP體元素的直接子元素。SOAP體元素的直接子元素可以限定名域。SOAP定義了SOAPFault元素來表示錯誤資訊。
4.1.1 SOAP encodingstyle屬性
Encodingstyle全域性屬性用來表示SOAP訊息的序列化規則。這個屬性可以在任何元素中出現,作用範圍與名域宣告的作用範圍很相似,為這個元素的內容和它的所有沒有過載此屬性的子元素。SOAP訊息沒有定義預設編碼。屬性值是一個或多個URI的順序列表,每個URI確定了一種或多種序列化規則,用來不同程度反序列化SOAP訊息,舉例如下:
"http://schemas.xmlsoap.org/soap/encoding/";
"http://my.host/encoding/restrictedhttp://my.host/encoding/";
""
第5節中定義的序列化規則由uri"http://schemas.xmlsoap.org/soap/encoding/"; 確定。使用這個特定序列化規則的訊息應該用encodingstyle屬性說明這一點。另外,所有以"http://schemas.xmlsoap.org/soap/encoding/";開頭的URI中的序列化規則與第5節中定義的SOAP編碼規則相一致。一個零長度的URI("")明確顯示所含元素沒有任何編碼形式。這可以用來取消上一級元素的所有編碼宣告。
4.1.2 封裝版本模型
SOAP沒有定義常規的基於主版本號和輔版本號的版本形式。SOAP訊息必須有一個封裝元素與名域"http://schemas.xmlsoap.org/soap/envelope/";關聯。如果SOAP應用程式接收到的SOAP訊息中的SOAP封裝元素與其他的名域關聯,則視為版本錯誤,應用程式必須丟棄這個訊息。如果訊息是通過HTTP之類的請求/應答協議收到的,應用程式必須回答一個SOAP VersionMismatch 錯誤資訊(見4.4節)。
4.2 soap頭
SOAP為相互通訊的團體之間提供了一種很靈活的機制:在無須預先協定的情況下,以分散但標準的方式擴充套件訊息。可以在SOAP頭中新增條目實現這種擴充套件,典型的例子有認證,事務管理,支付等等。頭元素編碼為SOAP封裝元素的第一個直接子元素。頭元素的所有直接子元素稱作條目。條目的編碼規則如下:
一個條目有它的完整的元素名(包括名域uri和區域性名)確定。soap頭的直接子元素必須有名域限制。
SOAP encodingstyle屬性可以用來指示條目所用的編碼形式(見4.1.1節)
SOAP mustUnderstand屬性(見4.2.3節)和SOAPactor屬性(見4.2.2節)可以用來指示如何處理這個條目以及由誰來處理。(見4.2.1節)
4.2.1 使用頭屬性
這一節中定義的SOAP頭屬性確定了SOAP訊息的接收者應該怎樣按第2節中所述的方式處理訊息。產生SOAP訊息的SOAP應用程式,應該僅僅在SOAP頭元素的直接子元素中使用這些SOAP頭屬性。SOAP訊息的接收者必須忽略所有不在SOAP頭元素的直接子元素中SOAP頭屬性。下面的例子是一個SOAP頭,包括一個元素標誌符"Transaction","mustUnderstand"取值為"1"和數值5。這應該以如下方式編碼:
xmlns:t="some-URI" SOAP-ENV:mustUnderstand="1">
5
4.2.2 soap actor屬性
一個SOAP訊息從始節點到終節點的過程中,可能沿著訊息路徑經過一系列SOAP中間節點。一個SOAP中間節點是一個可以接收轉發SOAP訊息的應用程式。中間節點和終節點由URI區分。可能SOAP訊息的終節點並不需要所有部分,而在訊息路徑上的一個和幾個中間節點可能需要這些內容。頭元素的接收者扮演的角色類似於一個過濾器,防止這些只發給本接受者的訊息部分擴散到其它節點。即一個頭元素的接收者必須不轉發這些頭元素到SOAP訊息路徑上的下一個應用程式。同樣的,接收者可能插入一個相似的頭元素。SOAP actor全域性屬性可以用於指示頭元素的接收者。SOAP actor屬性的值是一個URI。
uri "http://schemas.xmlsoap.org/soap/actor/next";指出了第一個處理這個訊息的SOAP應用程式需要這個頭元素。這類似於HTTP頭中用Connection域表示hop-by-hop範圍模型。省略SOAP actor屬性表示接收者是SOAP訊息的終節點。如果這個屬性要生效,它必須出現在SOAP訊息例項中。(見第3節和4.2.1節)
4.2.3 soap mustunderstand屬性
SOAP mustUnderstand全域性屬性用來指示接受者在處理訊息時這個條目是否必須處理。條目的接收者由SOAP actor屬性定義(見4.2.2節)。MustUnderstand屬性的值是"1" 或 "0"。缺少SOAP mustUnderstand屬性在語義上等同於它的值為"0"。如果一個頭元素的SOAP mustUnderstand屬性的值是"1",那麼條目的接受者必須或者遵守語義(如以元素的全名傳送)並按照語義正確的處理,或者放棄處理訊息(見4.4節)。SOAP mustUnderstand 屬性考慮了訊息演變的準確性(robust evolution)。必須假定包含SOAP mustUnderstand屬性且值為"1"的元素以某種方式修改了它們的父元素或同層元素的語義。以這種方式連線元素確保了語義上的變化不會被那些不能完全理解它的接收者忽略。如果這個屬性要生效,它必須出現在SOAP訊息例項中。(見第3節和4.2.1節)
4.3 soap體
SOAP體元素提供了一個簡單的機制,使訊息的最終接收者能交換必要的資訊。使用體元素的典型情況包括配置RPC請求和錯誤報告。體元素編碼為SOAP封裝元素的直接子元素。如果已經有一個頭元素,那麼體元素必須緊跟在頭元素之後,否則它必須是SOAP封裝元素的第一個直接子元素。體元素的所有直接子元素稱作體條目,每個體條目在SOAP體元素中編碼為一個獨立的元素。條目的編碼規則如下:
一個條目由它的元素全名(包括名域uri和區域性名)確定。soap體元素的直接子元素可能是名域限制的。
SOAP encodingstyle屬性可能用來指示條目(見4.1.1節)的編碼方式。
SOAP定義了一個Fault條目用來報告錯誤資訊。(見4.4節)
4.3.1 SOAP頭和體的關係
雖然頭和體定義為獨立的元素,它們實際上是有關係的。體條目和頭條目的關係如下:體條目在語義上等同於actor屬性為預設值且mustUnderstand屬性值為"1"的頭條目。不使用actor屬性則表示預設的actor。(見4.2.2節)
4.4 soap錯誤
SOAP錯誤元素用於在SOAP訊息中攜帶錯誤和(或)狀態資訊。如果有SOAP錯誤元素,它必須以以體條目的方式出現,並且在一個體元素中最多出現一次。SOAP錯誤元素定義了以下四個子元素:
faultcode
faultcode元素給軟體提供了一個識別此錯誤的演算法機制。SOAP錯誤元素必須有faultcode子元素,並且它的值必須是一個合法的名(在[8]節定義)。SOAP定義一些SOAP faultcode描述基本的SOAP錯誤(見4.4.1節)。
faultstring
faultstring元素提供了一個錯誤解釋,而不是為了軟體處理。faultstring元素類似於HTTP中定義(見[5],第6.1節)的'Reason-Phrase'。SOAP錯誤元素必須有faultstring子元素,並且它應該提供一些錯誤本質的解釋資訊。
faultactor
faultactor元素提供了在訊息路徑上是誰導致了錯誤發生的資訊(見第2節)。它類似於SOAP actor屬性(見4.2.2節),只是SOAP actor指的是頭條目的目的地,faultactor指的是錯誤的來源。faultactor屬性的值是用來區分錯誤來源的URI。不是SOAP訊息的最終目的地的應用程式必須在SOAP Fault元素中包含faultactor元素。訊息的最終目的地可以使用faultactor元素明確的指示是它產生了這個錯誤(參見下面的detail元素)
detail
detail元素用來攜帶與Body元素有關的應用程式所要的錯誤資訊。如果Body元素的內容不能被成功的處理,則必須包含detail子元素。它不能用來攜帶屬於頭條目的錯誤資訊。頭條目的詳細出錯資訊必須由頭條目攜帶。Fault元素中沒有detail元素表示這個錯誤與Body元素的處理無關。在有錯誤的時候,這可以用來區分Body元素有沒有被正確的處理。detail元素的所有直接子元素稱作detail條目,並且每個detail條目在detail元素中編碼為獨立的元素。detail條目的編碼規則如下(參見例10): 一個detail條目由它的元素全名(包括名域URI和區域性名)確定。SOAP體元素的直接子元素可能是名域限制的。SOAP encodingstyle屬性可能用來指示detail條目(見4.1.1節)的編碼方式。也可以有其它的Fault子元素,只要它們是名域限制的。
4.4.1 SOAP 錯誤程式碼
在描述這個規範中定義的錯誤時,這一節中定義的Faultcode值必須用在faultcode元素中。這些faultcode值得名域標誌符為"http://schemas.xmlsoap.org/soap/envelope/";。定義這個規範之外的方法時推薦(不要求)使用這個名域。預設的SOAP faultcode值以可擴充套件的方式定義,允許定義新的SOAP faultcode值,並與現有的faultcode值向後相容。使用的機制類似於HTTP中定義的1xx, 2xx,3xx等基本的狀態類(見[5]第10節),不過,它們定義為XML合法名(見 [8] 第3節 ),而不是整數。 字元"."(點)作為faultcode的分隔符,點左邊的錯誤程式碼比右邊的錯誤程式碼更為普通。如:
client.authentication
這篇文件中定義的faultcode值是:
名稱 含義
VersionMismatch 處理方發現SOAP封裝元素有不合法的名域(見4.1.2節)
MustUnderstand 處理方不理解或者不服從一個包含值為"1"的
mustUnderstand 屬性的 SOAP頭元素的直接子元素。(見4.2.3節)
client
client錯誤類表示訊息的格式錯誤或者不包含適當的正確資訊。例如,訊息可能缺少正確的認證和支付資訊。一般地,它表示訊息不能不作修改就重發。參見4.4節
soap fault detail子元素的描述。
server
server錯誤類表示由於訊息的處理過程而不是訊息的內容本身使得訊息訊息不能正確的處理。例如,處理訊息時可能要與其它處理器通訊,但它沒有響應。這個訊息可能在遲一點的時間處理成功。 soap fault子元素的詳細資訊參見4.4節
5. soap編碼
SOAP編碼格式基於一個簡單的型別系統,概括了程式語言,資料庫和半結構化資料等型別系統的共同特性。一個型別或者是一個簡單的(標量的)型別,或者是由幾個部分組合而成的複合型別,其中每個部分都有自己的型別。以下將詳細描述這些型別。這一節定義了型別化物件的序列化規則。它分兩個層次。首先,給定一個與型別系統的符號系統一致的Schema(譯者注:這裡的schema不是符合XML語法的schema,而僅僅表示廣義的用於表示訊息結構的定義方式),就構造了XML語法的Schema。然後,給定一個型別系統的Schema和與這個Schema一致的特定的值,就構造了一個XML文件例項。反之,給定一個依照這些規則產生的XML文件例項和初始的Schema,就可以構造初始值的一個副本。這一節中定義的元素和屬性的名域標誌符為"http://schemas.xmlsoap.org/soap/encoding/";。下面的例子都假定在上一層的元素中宣告瞭名域。
鼓勵使用這一節中描述的資料模型和編碼方式,但也可以在SOAP中使用其他的資料模型和編碼方式。(見4.1.1節)
5.1 xml中的編碼型別規則
XML允許非常靈活的資料編碼方式。SOAP定義了一個較小的規則集合。這一節在總的層次上定義了這些編碼規則,下一節將描述特定型別的編碼規則的細節。這一節定義的編碼規則可以與第7節中所述的RPC呼叫和應答對映結合使用。下面的術語用來描述編碼規則:
一個"value"是一個字串,型別(數字,日期,列舉等等)的名或是幾個簡單值的組合。所有的值都有特定的型別。
一個"simple value"沒有名部分, 如特定的字串,整數,列舉值等等。
一個"compound value"是相關的值的結合,如定單,股票報表,街道地址等等。在"compound value"中,每個相關的值都潛在的以名,序數或這兩者來區分。這叫作"a ccessor"。複合值的例子有定單和股票報表等等。陣列也是複合值。在複合值中,多個accessor有相同的名是允許的,例如RDF就是這樣做的。
一個"array"是一個複合值,成員值按照在陣列中的位置相互區分。
一個"struct"也是一個複合值,成員值之間的唯一區別是accessor名,accessor名互不相同。
一個"simple type"是簡單值的類,如叫做"string" "integer"的類,還有列舉類等等。
一個"compound type"是複合值的類。複合型別的例子有定單類,它們有相同的accessor名(shipTo, totalCost等),但可能會有不同的值(可能以後被設定為確定的值)。
在複合型別中,如果型別內的accessor名互不相同,但是可能與其他型別中的accessor名相同,即,accessor名加上型別名形成一個唯一的標誌符,這個名叫作"區域性範圍名"。如果名是直接或間接的基於URI的一部分,那麼不管它出現在什麼型別中,這個名本身就可以唯一標誌這個accessor,這樣的名叫作"全域性範圍名"。給定了schema中相關的值的序列化資訊,就可能確定某些值只與某個accessor的一個例項有關。其它情況下則無法確定。當且僅當一個accessor引用一個值,這個值才能被視為"single-reference",如果有不止一個accessor引用它,那麼就將它視為"multi-reference"。注意,可能一個確定的值在一個schema中是"single-reference",而在另一個schema中是"multi-reference"。在語句構成上,一個元素可能是"independent" 或 "embedded"。一個獨立的元素指出現在序列化最頂層的任何元素。所有其它元素都是嵌入元素。雖然用xsi:type屬性可以使值的結構和型別變為自描述的,但是序列化規則允許值的型別僅僅參照schema而定。這樣的schema可能使用"XML Schema Part 1: Structures" [10]和"XML Schema Part 2: Datatypes" [11]中描述的符號系統,也可能使用其它符號系統。注意,雖然序列化規則可以用於除了陣列和結構之外的複合型別,但是許多schema僅僅包含陣列和結構型別。序列化規則如下:
所有的值以元素內容的形式表示。一個multi-reference值必須表示為一個獨立元素的內容,而一個single-reference值最好不要這樣表示(也可以這樣表示)。對於每個具有值的元素,值的型別時必須用下述三種方式之一描述:
所屬元素例項有xsi:type屬性
所屬元素是一個有SOAP-ENC:arrayType 屬性(該屬性可能是預設的)的元素的子元素,或者
所屬元素的名具有特定的型別,型別可以由schema確定。
一個簡單值表示為字元資料,即沒有任何子元素。每個簡單值必須具有一個型別,這個型別或者是XML Schemas Specification, part 2 [11]有的型別,或者具有源型別(參見5.2節)。一個複合值編碼成一個元素的序列,每個accessor用一個嵌入元素表示,該元素的元素名和accessor的名一致。如果accessor的名是區域性於其所屬的型別的,則該元素的元素名不是合格的,否則對應的元素名是合格的。(參見5.4節)
一個multi-reference的簡單值或複合值編碼成一個獨立的元素,這個元素包含一個區域性的無需校驗的屬性,屬性名為"id",型別為"ID"(依照XML Specification [7])。值的每個accessor對應一個空元素,該元素有一個區域性的,無需校驗的屬性,屬性名為"href",型別為" uri-reference "(依照XML Schema Specification [11]),"href"屬性的值引用了相對應的獨立元素的URI標誌符。字串和字元陣列表示為multi-reference的簡單型別,但是特殊的規則使它們在普通的情況下能被更有效的表示(參見5.2.1節和5.2.3節)。字串和字元陣列值的accessor可能有一個名字為"id",型別為"ID"(依照XML Specification [7])的屬性。如果這樣,所有這個值的所有其它accessor編碼成一個空元素,這個元素有一個區域性的,無需校驗的屬性,屬性名為"href",型別為" uri-reference "(依照XML Schema Specification [11]),"href"屬性的值引用了包含這個值的元素的URI標誌符。編碼時允許一個值有多個引用,就像多個不同的值有多個引用一樣,但這僅在從上下文可以知道這個XML文件例項的含義沒有改變時才可使用。陣列是複合值(參見5.4.2節)。SOAP陣列定義為具有型別"SOAP-ENC:Array"或從它衍生的型別.
soap陣列可以時一維或多維,它們的成員以序數位置相互區分。一個陣列值表示為反映這個陣列的一系列元素,陣列成員按升序出現。對多維陣列來說,右邊的這一維變化最快。每個成員元素命名為一個獨立元素。(見規則2)soap陣列可以是single-reference 或multi-reference值,因此可以表示為嵌入元素或獨立元素的內容。soap陣列必須包含一個"soap-enc:arraytype"屬性,它的值指定了包含元素的型別和陣列的維數。"soap-enc:arraytype"屬性的值定義如下:
arraytypevalue = atype asize
atype = QName *( rank )
rank = "[" *( "," ) "]"
asize = "[" #length "]"
length = 1*DIGIT
"atype"結構是被包含元素的型別名,它表示為qname並且作為型別限制在xml元素宣告的
"type"屬性中出現(這意味著被包含元素的所有值都要與該型別一致,即在SOAP-ENC:a rrayType中引用的型別必須是每個陣列成員的型別或超型別)。在arrays of arrays or "jagged arrays"的情況下,型別元件編碼為"innermost"型別且在從第一層開始的巢狀陣列的每一層中,型別名後都跟隨一個rank結構。多維陣列編碼時從第一維起,每一維之間用逗號隔開。
"asize"結構包含一個以逗號分隔的列表,數值0,1或其它整數表示陣列每一維的長度。整數0表示沒有指定詳細的大小,但是可能在檢查陣列實際成員的大小後確定。例如,一個5個成員的整型陣列的arrayTypevalue值為"int[][5]",它的atype值是int[]",asize值是"[5]"。同樣,一個3個成員的兩維整型陣列的arrayTypevalue值為"int[,][3]",它的atype值是int[,]",asize值是"[3]"。
一個SOAP陣列成員可能包含一個"SOAP-ENC:offset"屬性表示這一項在整個陣列中的位置偏移值。這被用來指示一個部分儲值陣列(見5.4.2.1節)的位置偏移值。同樣,一個陣列成員可能包含一個"SOAP-ENC:position"屬性表示這一項在整個陣列中的位置,這被用來描述稀疏陣列(見5.4.2.2節)的成員。"SOAP-ENC:offset" 和"SOAP-ENC:position"屬性值的定義如下:
arraypoint = "[" #length "]"
偏移值和位置從0開始
NULL值或預設值可能通過省略accssor元素來表示。NULL值也可能通過一個包含值為'1'的xsi:null屬性的accssor元素來表示,其它的依賴於應用程式的屬性和值也可能用來表示NULL值。注意,規則2允許獨立的元素和陣列成員名不同於值型別的元素。
1. 簡介
SOAP以XML形式提供了一個簡單、輕量的用於在分散或分佈環境中交換結構化和型別資訊的機制。SOAP本身並沒有定義任何應用程式語義,如程式設計模型或特定語義的實現;實際上它通過提供一個有標準元件的包模型和在模組中編碼資料的機制,定義了一個簡單的表示應用程式語義的機制。這使SOAP能夠被用於從訊息傳遞到RPC的各種系統。
soap包括三個部分
soap封裝(見第4節)結構定義了一個整體框架用來表示訊息中包含什麼內容,誰來處理這些內容以及這些內容是可選的或是必需的。
SOAP編碼規則(見第5節)定義了用以交換應用程式定義的資料型別的例項的一系列機制。
SOAP RPC表示(見第7節)定義了一個用來表示遠端過程呼叫和應答的協定。
雖然這三個部分都作為SOAP的一部分一起描述,但它們在功能上是相交的。特別的,封裝和編碼規則是在不同的名域中定義的,這種模組性的定義方法增加了簡單性在SOAP封裝,SOAP編碼規則和SOAPRPC協定之外,這個規範還定義了兩個協議的繫結,描述了在有或沒有HTTP擴充套件框架[6]的情況下,SOAP訊息如何包含在HTTP訊息[5]中被傳送。
1.1 設計目標
SOAP的主要設計目標是簡單性和可擴充套件性,這意味著傳統的訊息系統和分佈物件系統的某些性質不是SOAP規範的一部分。這些性質包括:
分散式碎片收集
成批傳送訊息
物件引用(要求分散式碎片收集)
啟用機制(要求物件引用)
1.2 符號約定
這篇文章中的關鍵字 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT","SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 和"OPTIONAL"的解釋在RFC-2119 [2]中。 這篇文章中用到的名域字首 "SOAP-ENV" 和"SOAP-ENC"分別與"http://schemas.xmlsoap.org/soap/envelope/"; 和"http://schemas.xmlsoap.org/soap/encoding/";關聯。整篇文件中,名域字首“xsi”被假定為與URI"http://www.w3.org/1999/XMLSchema-instance“(在XMLSchema規範[11]定義)相連。類似的,名域字首”xsd“被假定為與URI"http://www.w3.org/1999/XMLSchema";(在[10]中定義)相連。名域字首”tns“用來表示任意名域。所有其它的名域字首都只是例子。
名域URI的基本形式”some-URI“表示某些依賴於應用程式或上下文的URI[4]。這個規範用擴充套件BNF(在RFC-2616[5] 描述)描述某些結構。
1.3 soap訊息舉例
在這個例子中,GetLastTradePrice SOAP 請求被髮往StockQuote服務。這個請求攜帶一個字串引數和ticker符號,在SOAP應答中返回一個浮點數。XML名域用來區分SOAP標誌符和應用程式特定的標誌符。這個例子說明了在第6節中定義的HTTP繫結。如果SOAP中管理XML負載的規則完全獨立於HTTP是沒有意義的,因為事實上該負載是由HTTP攜帶的。在Appendix A中有更多的例子。
例1 在http請求中嵌入soap訊息
post /stockquote http/1.1
Host:
www.stockquoteserver.com
Content-Type: text/xml;
charset="utf-8"
Content-Length: nnnn
SOAPAction:
"Some-URI"
SOAP-ENV:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/";>
下面是一條應答訊息,包括http訊息,soap訊息是其具體內容 :
例2 在http應答中嵌入soap訊息
http/1.1 200 ok
Content-Type: text/xml;
charset="utf-8"
Content-Length:
nnnn
SOAP-ENV:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/";/>
2. soap訊息交換模型
SOAP訊息從傳送方到接收方是單向傳送,但正如上面顯示的,SOAP訊息經常以請求/應答的方式實現。SOAP實現可以通過開發特定網路系統的特性來優化。例如,HTTP繫結(見第6節)使SOAP應答訊息以HTTP應答的方式傳輸,並使用同一個連線返回請求。不管SOAP被繫結到哪個協議,SOAP訊息採用所謂的”訊息路徑“傳送,這使在終節點之外的中間節點可以處理訊息。一個接收SOAP訊息的SOAP應用程式必須按順序執行以下的動作來處理訊息:識別應用程式想要的SOAP訊息的所有部分 (見4.2.2節)檢驗應用程式是否支援第一步中識別的訊息中所有必需部分並處理它。如果不支援,則丟棄訊息(見4.4節)。在不影響處理結果的情況下,處理器可能忽略第一步中識別出的可選部分。如果這個SOAP應用程式不是這個訊息的最終目的地,則在轉發訊息之前刪除第一步中識別出來的所有部分。為了正確處理一條訊息或者訊息的一部分,SOAP處理器需要理解:所用的交換方式(單向,請求/應答,多路傳送等等),這種方式下接收者的任務,RPC機制(如果有的話)的使用(如第7節中所述),資料的表現方法或編碼,還有其它必需的語義。儘管屬性(比如SOAP encodingstyle,見4.1.1節)可以用於描述一個訊息的某些方面,但這個規範並不 強制所有的接收方也必須有同樣的屬性並取同樣的屬性值。舉個例子,某一特定的應用可能知道一個元素表示一條遵循第7節約定的RPC請求,但是另外一些應用可能認為指向該元素的所有訊息都用單向傳輸,而不是類似第7節的請求應答模式。
(譯者注:互動雙方的SOAP訊息並不一定要遵循同樣的格式設定,而只需要以一種雙方可理解的格式交換資訊就可以了)
3. 與xml的關係
所有的SOAP訊息都使用XML形式編碼(更多有關XML的資訊請見[7])一個SOAP應用程式產生的訊息中,所有由SOAP定義的元素和屬性中必須包括正確的名域。SOAP應用程式必須能夠處理它接收到的訊息中的SOAP名域(見4.4節),並且它可以處理沒有SOAP名域的SOAP訊息,就象它們有正確的名域一樣。SOAP定義了兩個名域(更多有關XML名域的資訊請見[8])
soap封裝的名域標誌符是"http://schemas.xmlsoap.org/soap/envelope/";
SOAP的編碼規則的名域標誌符是"http://schemas.xmlsoap.org/soap/encoding/";
SOAP訊息中不能包含文件型別宣告,也不能包括訊息處理指令。[7] SOAP使用"ID"型別"id"屬性來指定一個元素的唯一的標誌符,同時該屬性是區域性的和無需校驗的。SOAP使用"uri-reference"型別的"href"屬性指定對這個值的引用,同時該屬性是區域性的和無需校驗的。這樣就遵從了XML規範[7],XMLSchema規範[11]和XML連線語言規範[9]的風格。除了SOAP mustUnderstand 屬性(見4.2.3節)和SOAPactor屬性(見4.2.2節)之外,一般允許屬性和它們的值出現在XML文件例項或Schema中(兩者效果相同)。也就是說,在DTD或Schema中宣告一個預設值或固定值和在XML文件例項中設定它的值在語義上相同。
4. soap封裝
SOAP訊息是一個XML文件,包括一個必需的SOAP封裝,一個可選的SOAP頭和一個必需的SOAP體。在這篇規範剩餘部分中,提到SOAP訊息時就是指這個XML文件。這一節中定義的元素和屬性的名域標誌符為:
"http://schemas.xmlsoap.org/soap/envelope/"; 。一個SOAP訊息包括以下部分:1.在表示這個訊息的XML文件中,封裝是頂層元素。2.應用SOAP交換資訊的各方是分散的且沒有預先協定,SOAP頭提供了向SOAP訊息中新增關於這條SOAP訊息的某些要素(feature)的機制。SOAP定義了少量的屬性用來表明這項要素(feature)是否可選以及由誰來處理。(見4.2節)3.SOAP體是包含訊息的最終接收者想要的資訊的容器(見4.3節)。SOAP為SOAP體定義了一個Fault元素用來報告錯誤資訊。語法規則如下所示:
封裝
元素名是 "envelope"
在SOAP訊息中必須出現。
可以包含名域宣告和附加屬性。如果包含附加屬性,這些屬性必須限定名域。類似的,"Envelope"可以包含附加子元素,這些也必須限定名域且跟在SOAP體元素之後。
SOAP頭 (見4.2節)
元素名是"header"
在SOAP訊息中可能出現。如果出現的話,必須是SOAP封裝元素的第一個直接子元素。
SOAP頭可以包含多個條目,每個都是SOAP頭元素的直接子元素。所有SOAP頭的直接子元素都必須限定名域。
SOAP體 (見4.3節)
元素名是"body"
在SOAP訊息中必須出現且必須是SOAP封裝元素的直接子元素。它必須直接跟在SOAP頭元素(如果有)之後。否則它必須是SOAP封裝元素的第一個直接子元素。
SOAP體可以包括多個條目,每個條目必須是SOAP體元素的直接子元素。SOAP體元素的直接子元素可以限定名域。SOAP定義了SOAPFault元素來表示錯誤資訊。
4.1.1 SOAP encodingstyle屬性
Encodingstyle全域性屬性用來表示SOAP訊息的序列化規則。這個屬性可以在任何元素中出現,作用範圍與名域宣告的作用範圍很相似,為這個元素的內容和它的所有沒有過載此屬性的子元素。SOAP訊息沒有定義預設編碼。屬性值是一個或多個URI的順序列表,每個URI確定了一種或多種序列化規則,用來不同程度反序列化SOAP訊息,舉例如下:
"http://schemas.xmlsoap.org/soap/encoding/";
"http://my.host/encoding/restrictedhttp://my.host/encoding/";
""
第5節中定義的序列化規則由uri"http://schemas.xmlsoap.org/soap/encoding/"; 確定。使用這個特定序列化規則的訊息應該用encodingstyle屬性說明這一點。另外,所有以"http://schemas.xmlsoap.org/soap/encoding/";開頭的URI中的序列化規則與第5節中定義的SOAP編碼規則相一致。一個零長度的URI("")明確顯示所含元素沒有任何編碼形式。這可以用來取消上一級元素的所有編碼宣告。
4.1.2 封裝版本模型
SOAP沒有定義常規的基於主版本號和輔版本號的版本形式。SOAP訊息必須有一個封裝元素與名域"http://schemas.xmlsoap.org/soap/envelope/";關聯。如果SOAP應用程式接收到的SOAP訊息中的SOAP封裝元素與其他的名域關聯,則視為版本錯誤,應用程式必須丟棄這個訊息。如果訊息是通過HTTP之類的請求/應答協議收到的,應用程式必須回答一個SOAP VersionMismatch 錯誤資訊(見4.4節)。
4.2 soap頭
SOAP為相互通訊的團體之間提供了一種很靈活的機制:在無須預先協定的情況下,以分散但標準的方式擴充套件訊息。可以在SOAP頭中新增條目實現這種擴充套件,典型的例子有認證,事務管理,支付等等。頭元素編碼為SOAP封裝元素的第一個直接子元素。頭元素的所有直接子元素稱作條目。條目的編碼規則如下:
一個條目有它的完整的元素名(包括名域uri和區域性名)確定。soap頭的直接子元素必須有名域限制。
SOAP encodingstyle屬性可以用來指示條目所用的編碼形式(見4.1.1節)
SOAP mustUnderstand屬性(見4.2.3節)和SOAPactor屬性(見4.2.2節)可以用來指示如何處理這個條目以及由誰來處理。(見4.2.1節)
4.2.1 使用頭屬性
這一節中定義的SOAP頭屬性確定了SOAP訊息的接收者應該怎樣按第2節中所述的方式處理訊息。產生SOAP訊息的SOAP應用程式,應該僅僅在SOAP頭元素的直接子元素中使用這些SOAP頭屬性。SOAP訊息的接收者必須忽略所有不在SOAP頭元素的直接子元素中SOAP頭屬性。下面的例子是一個SOAP頭,包括一個元素標誌符"Transaction","mustUnderstand"取值為"1"和數值5。這應該以如下方式編碼:
5
4.2.2 soap actor屬性
一個SOAP訊息從始節點到終節點的過程中,可能沿著訊息路徑經過一系列SOAP中間節點。一個SOAP中間節點是一個可以接收轉發SOAP訊息的應用程式。中間節點和終節點由URI區分。可能SOAP訊息的終節點並不需要所有部分,而在訊息路徑上的一個和幾個中間節點可能需要這些內容。頭元素的接收者扮演的角色類似於一個過濾器,防止這些只發給本接受者的訊息部分擴散到其它節點。即一個頭元素的接收者必須不轉發這些頭元素到SOAP訊息路徑上的下一個應用程式。同樣的,接收者可能插入一個相似的頭元素。SOAP actor全域性屬性可以用於指示頭元素的接收者。SOAP actor屬性的值是一個URI。
uri "http://schemas.xmlsoap.org/soap/actor/next";指出了第一個處理這個訊息的SOAP應用程式需要這個頭元素。這類似於HTTP頭中用Connection域表示hop-by-hop範圍模型。省略SOAP actor屬性表示接收者是SOAP訊息的終節點。如果這個屬性要生效,它必須出現在SOAP訊息例項中。(見第3節和4.2.1節)
4.2.3 soap mustunderstand屬性
SOAP mustUnderstand全域性屬性用來指示接受者在處理訊息時這個條目是否必須處理。條目的接收者由SOAP actor屬性定義(見4.2.2節)。MustUnderstand屬性的值是"1" 或 "0"。缺少SOAP mustUnderstand屬性在語義上等同於它的值為"0"。如果一個頭元素的SOAP mustUnderstand屬性的值是"1",那麼條目的接受者必須或者遵守語義(如以元素的全名傳送)並按照語義正確的處理,或者放棄處理訊息(見4.4節)。SOAP mustUnderstand 屬性考慮了訊息演變的準確性(robust evolution)。必須假定包含SOAP mustUnderstand屬性且值為"1"的元素以某種方式修改了它們的父元素或同層元素的語義。以這種方式連線元素確保了語義上的變化不會被那些不能完全理解它的接收者忽略。如果這個屬性要生效,它必須出現在SOAP訊息例項中。(見第3節和4.2.1節)
4.3 soap體
SOAP體元素提供了一個簡單的機制,使訊息的最終接收者能交換必要的資訊。使用體元素的典型情況包括配置RPC請求和錯誤報告。體元素編碼為SOAP封裝元素的直接子元素。如果已經有一個頭元素,那麼體元素必須緊跟在頭元素之後,否則它必須是SOAP封裝元素的第一個直接子元素。體元素的所有直接子元素稱作體條目,每個體條目在SOAP體元素中編碼為一個獨立的元素。條目的編碼規則如下:
一個條目由它的元素全名(包括名域uri和區域性名)確定。soap體元素的直接子元素可能是名域限制的。
SOAP encodingstyle屬性可能用來指示條目(見4.1.1節)的編碼方式。
SOAP定義了一個Fault條目用來報告錯誤資訊。(見4.4節)
4.3.1 SOAP頭和體的關係
雖然頭和體定義為獨立的元素,它們實際上是有關係的。體條目和頭條目的關係如下:體條目在語義上等同於actor屬性為預設值且mustUnderstand屬性值為"1"的頭條目。不使用actor屬性則表示預設的actor。(見4.2.2節)
4.4 soap錯誤
SOAP錯誤元素用於在SOAP訊息中攜帶錯誤和(或)狀態資訊。如果有SOAP錯誤元素,它必須以以體條目的方式出現,並且在一個體元素中最多出現一次。SOAP錯誤元素定義了以下四個子元素:
faultcode
faultcode元素給軟體提供了一個識別此錯誤的演算法機制。SOAP錯誤元素必須有faultcode子元素,並且它的值必須是一個合法的名(在[8]節定義)。SOAP定義一些SOAP faultcode描述基本的SOAP錯誤(見4.4.1節)。
faultstring
faultstring元素提供了一個錯誤解釋,而不是為了軟體處理。faultstring元素類似於HTTP中定義(見[5],第6.1節)的'Reason-Phrase'。SOAP錯誤元素必須有faultstring子元素,並且它應該提供一些錯誤本質的解釋資訊。
faultactor
faultactor元素提供了在訊息路徑上是誰導致了錯誤發生的資訊(見第2節)。它類似於SOAP actor屬性(見4.2.2節),只是SOAP actor指的是頭條目的目的地,faultactor指的是錯誤的來源。faultactor屬性的值是用來區分錯誤來源的URI。不是SOAP訊息的最終目的地的應用程式必須在SOAP Fault元素中包含faultactor元素。訊息的最終目的地可以使用faultactor元素明確的指示是它產生了這個錯誤(參見下面的detail元素)
detail
detail元素用來攜帶與Body元素有關的應用程式所要的錯誤資訊。如果Body元素的內容不能被成功的處理,則必須包含detail子元素。它不能用來攜帶屬於頭條目的錯誤資訊。頭條目的詳細出錯資訊必須由頭條目攜帶。Fault元素中沒有detail元素表示這個錯誤與Body元素的處理無關。在有錯誤的時候,這可以用來區分Body元素有沒有被正確的處理。detail元素的所有直接子元素稱作detail條目,並且每個detail條目在detail元素中編碼為獨立的元素。detail條目的編碼規則如下(參見例10): 一個detail條目由它的元素全名(包括名域URI和區域性名)確定。SOAP體元素的直接子元素可能是名域限制的。SOAP encodingstyle屬性可能用來指示detail條目(見4.1.1節)的編碼方式。也可以有其它的Fault子元素,只要它們是名域限制的。
4.4.1 SOAP 錯誤程式碼
在描述這個規範中定義的錯誤時,這一節中定義的Faultcode值必須用在faultcode元素中。這些faultcode值得名域標誌符為"http://schemas.xmlsoap.org/soap/envelope/";。定義這個規範之外的方法時推薦(不要求)使用這個名域。預設的SOAP faultcode值以可擴充套件的方式定義,允許定義新的SOAP faultcode值,並與現有的faultcode值向後相容。使用的機制類似於HTTP中定義的1xx, 2xx,3xx等基本的狀態類(見[5]第10節),不過,它們定義為XML合法名(見 [8] 第3節 ),而不是整數。 字元"."(點)作為faultcode的分隔符,點左邊的錯誤程式碼比右邊的錯誤程式碼更為普通。如:
client.authentication
這篇文件中定義的faultcode值是:
名稱 含義
VersionMismatch 處理方發現SOAP封裝元素有不合法的名域(見4.1.2節)
MustUnderstand 處理方不理解或者不服從一個包含值為"1"的
mustUnderstand 屬性的 SOAP頭元素的直接子元素。(見4.2.3節)
client
client錯誤類表示訊息的格式錯誤或者不包含適當的正確資訊。例如,訊息可能缺少正確的認證和支付資訊。一般地,它表示訊息不能不作修改就重發。參見4.4節
soap fault detail子元素的描述。
server
server錯誤類表示由於訊息的處理過程而不是訊息的內容本身使得訊息訊息不能正確的處理。例如,處理訊息時可能要與其它處理器通訊,但它沒有響應。這個訊息可能在遲一點的時間處理成功。 soap fault子元素的詳細資訊參見4.4節
5. soap編碼
SOAP編碼格式基於一個簡單的型別系統,概括了程式語言,資料庫和半結構化資料等型別系統的共同特性。一個型別或者是一個簡單的(標量的)型別,或者是由幾個部分組合而成的複合型別,其中每個部分都有自己的型別。以下將詳細描述這些型別。這一節定義了型別化物件的序列化規則。它分兩個層次。首先,給定一個與型別系統的符號系統一致的Schema(譯者注:這裡的schema不是符合XML語法的schema,而僅僅表示廣義的用於表示訊息結構的定義方式),就構造了XML語法的Schema。然後,給定一個型別系統的Schema和與這個Schema一致的特定的值,就構造了一個XML文件例項。反之,給定一個依照這些規則產生的XML文件例項和初始的Schema,就可以構造初始值的一個副本。這一節中定義的元素和屬性的名域標誌符為"http://schemas.xmlsoap.org/soap/encoding/";。下面的例子都假定在上一層的元素中宣告瞭名域。
鼓勵使用這一節中描述的資料模型和編碼方式,但也可以在SOAP中使用其他的資料模型和編碼方式。(見4.1.1節)
5.1 xml中的編碼型別規則
XML允許非常靈活的資料編碼方式。SOAP定義了一個較小的規則集合。這一節在總的層次上定義了這些編碼規則,下一節將描述特定型別的編碼規則的細節。這一節定義的編碼規則可以與第7節中所述的RPC呼叫和應答對映結合使用。下面的術語用來描述編碼規則:
一個"value"是一個字串,型別(數字,日期,列舉等等)的名或是幾個簡單值的組合。所有的值都有特定的型別。
一個"simple value"沒有名部分, 如特定的字串,整數,列舉值等等。
一個"compound value"是相關的值的結合,如定單,股票報表,街道地址等等。在"compound value"中,每個相關的值都潛在的以名,序數或這兩者來區分。這叫作"a ccessor"。複合值的例子有定單和股票報表等等。陣列也是複合值。在複合值中,多個accessor有相同的名是允許的,例如RDF就是這樣做的。
一個"array"是一個複合值,成員值按照在陣列中的位置相互區分。
一個"struct"也是一個複合值,成員值之間的唯一區別是accessor名,accessor名互不相同。
一個"simple type"是簡單值的類,如叫做"string" "integer"的類,還有列舉類等等。
一個"compound type"是複合值的類。複合型別的例子有定單類,它們有相同的accessor名(shipTo, totalCost等),但可能會有不同的值(可能以後被設定為確定的值)。
在複合型別中,如果型別內的accessor名互不相同,但是可能與其他型別中的accessor名相同,即,accessor名加上型別名形成一個唯一的標誌符,這個名叫作"區域性範圍名"。如果名是直接或間接的基於URI的一部分,那麼不管它出現在什麼型別中,這個名本身就可以唯一標誌這個accessor,這樣的名叫作"全域性範圍名"。給定了schema中相關的值的序列化資訊,就可能確定某些值只與某個accessor的一個例項有關。其它情況下則無法確定。當且僅當一個accessor引用一個值,這個值才能被視為"single-reference",如果有不止一個accessor引用它,那麼就將它視為"multi-reference"。注意,可能一個確定的值在一個schema中是"single-reference",而在另一個schema中是"multi-reference"。在語句構成上,一個元素可能是"independent" 或 "embedded"。一個獨立的元素指出現在序列化最頂層的任何元素。所有其它元素都是嵌入元素。雖然用xsi:type屬性可以使值的結構和型別變為自描述的,但是序列化規則允許值的型別僅僅參照schema而定。這樣的schema可能使用"XML Schema Part 1: Structures" [10]和"XML Schema Part 2: Datatypes" [11]中描述的符號系統,也可能使用其它符號系統。注意,雖然序列化規則可以用於除了陣列和結構之外的複合型別,但是許多schema僅僅包含陣列和結構型別。序列化規則如下:
所有的值以元素內容的形式表示。一個multi-reference值必須表示為一個獨立元素的內容,而一個single-reference值最好不要這樣表示(也可以這樣表示)。對於每個具有值的元素,值的型別時必須用下述三種方式之一描述:
所屬元素例項有xsi:type屬性
所屬元素是一個有SOAP-ENC:arrayType 屬性(該屬性可能是預設的)的元素的子元素,或者
所屬元素的名具有特定的型別,型別可以由schema確定。
一個簡單值表示為字元資料,即沒有任何子元素。每個簡單值必須具有一個型別,這個型別或者是XML Schemas Specification, part 2 [11]有的型別,或者具有源型別(參見5.2節)。一個複合值編碼成一個元素的序列,每個accessor用一個嵌入元素表示,該元素的元素名和accessor的名一致。如果accessor的名是區域性於其所屬的型別的,則該元素的元素名不是合格的,否則對應的元素名是合格的。(參見5.4節)
一個multi-reference的簡單值或複合值編碼成一個獨立的元素,這個元素包含一個區域性的無需校驗的屬性,屬性名為"id",型別為"ID"(依照XML Specification [7])。值的每個accessor對應一個空元素,該元素有一個區域性的,無需校驗的屬性,屬性名為"href",型別為" uri-reference "(依照XML Schema Specification [11]),"href"屬性的值引用了相對應的獨立元素的URI標誌符。字串和字元陣列表示為multi-reference的簡單型別,但是特殊的規則使它們在普通的情況下能被更有效的表示(參見5.2.1節和5.2.3節)。字串和字元陣列值的accessor可能有一個名字為"id",型別為"ID"(依照XML Specification [7])的屬性。如果這樣,所有這個值的所有其它accessor編碼成一個空元素,這個元素有一個區域性的,無需校驗的屬性,屬性名為"href",型別為" uri-reference "(依照XML Schema Specification [11]),"href"屬性的值引用了包含這個值的元素的URI標誌符。編碼時允許一個值有多個引用,就像多個不同的值有多個引用一樣,但這僅在從上下文可以知道這個XML文件例項的含義沒有改變時才可使用。陣列是複合值(參見5.4.2節)。SOAP陣列定義為具有型別"SOAP-ENC:Array"或從它衍生的型別.
soap陣列可以時一維或多維,它們的成員以序數位置相互區分。一個陣列值表示為反映這個陣列的一系列元素,陣列成員按升序出現。對多維陣列來說,右邊的這一維變化最快。每個成員元素命名為一個獨立元素。(見規則2)soap陣列可以是single-reference 或multi-reference值,因此可以表示為嵌入元素或獨立元素的內容。soap陣列必須包含一個"soap-enc:arraytype"屬性,它的值指定了包含元素的型別和陣列的維數。"soap-enc:arraytype"屬性的值定義如下:
arraytypevalue = atype asize
atype = QName *( rank )
rank = "[" *( "," ) "]"
asize = "[" #length "]"
length = 1*DIGIT
"atype"結構是被包含元素的型別名,它表示為qname並且作為型別限制在xml元素宣告的
"type"屬性中出現(這意味著被包含元素的所有值都要與該型別一致,即在SOAP-ENC:a rrayType中引用的型別必須是每個陣列成員的型別或超型別)。在arrays of arrays or "jagged arrays"的情況下,型別元件編碼為"innermost"型別且在從第一層開始的巢狀陣列的每一層中,型別名後都跟隨一個rank結構。多維陣列編碼時從第一維起,每一維之間用逗號隔開。
"asize"結構包含一個以逗號分隔的列表,數值0,1或其它整數表示陣列每一維的長度。整數0表示沒有指定詳細的大小,但是可能在檢查陣列實際成員的大小後確定。例如,一個5個成員的整型陣列的arrayTypevalue值為"int[][5]",它的atype值是int[]",asize值是"[5]"。同樣,一個3個成員的兩維整型陣列的arrayTypevalue值為"int[,][3]",它的atype值是int[,]",asize值是"[3]"。
一個SOAP陣列成員可能包含一個"SOAP-ENC:offset"屬性表示這一項在整個陣列中的位置偏移值。這被用來指示一個部分儲值陣列(見5.4.2.1節)的位置偏移值。同樣,一個陣列成員可能包含一個"SOAP-ENC:position"屬性表示這一項在整個陣列中的位置,這被用來描述稀疏陣列(見5.4.2.2節)的成員。"SOAP-ENC:offset" 和"SOAP-ENC:position"屬性值的定義如下:
arraypoint = "[" #length "]"
偏移值和位置從0開始
NULL值或預設值可能通過省略accssor元素來表示。NULL值也可能通過一個包含值為'1'的xsi:null屬性的accssor元素來表示,其它的依賴於應用程式的屬性和值也可能用來表示NULL值。注意,規則2允許獨立的元素和陣列成員名不同於值型別的元素。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25897606/viewspace-756792/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SOAP協議規範(二)協議
- Mqtt協議規範MQQT協議
- 網路協議規範大全協議
- 瞭解下SOAP HTTP 協議HTTP協議
- 用Python寫協議規範Python協議
- soap協議的web服務協議Web
- TELNET協議規範(中文版) (轉)協議
- Http get,post,soap協議的區別HTTP協議
- onvif soap 協議的錯誤程式碼協議
- POP3協議規範(中文版) (轉)協議
- 【譯】 WebSocket 協議第十二章——使用其他規範中的WebSocket協議Web協議
- Ajax通過SOAP協議呼叫Web服務協議Web
- SOAP協議棧是令人尷尬的失敗?協議
- HTTP和SOAP完全就是兩個不同的協議HTTP協議
- 雲協議範例一 P2P協議
- HTML編碼規範建議HTML
- 作者:Don Box 簡單物件訪問協議(SOAP)初級指南 (轉)物件協議
- 從規範看ECMAScript(一):規範基礎
- Neuron 2.1.0 釋出:支援 Sparkplug B 規範,更完善的工業協議支援Spark協議
- apache cxf-2.4.3 +spring-3.0.5釋出SOAP協議WebService服務ApacheSpring協議Web
- 前端開發規範:命名規範、html規範、css規範、js規範前端HTMLCSSJS
- MySQL 高效能優化規範建議MySql優化
- CSS編寫指導規範和建議CSS
- 一攬子協議協議
- 快取一致性協議(MESI協議)快取協議
- 【網路協議】IP協議、ARP協議、RARP協議協議
- MySQL資料庫規範 (設計規範+開發規範+操作規範)MySql資料庫
- (1) Mysql高效能優化規範建議MySql優化
- 泛議網路表單可用性規範
- 資料探勘實驗(一)資料規範化【最小-最大規範化、零-均值規範化、小數定標規範化】
- 前端規範之javascript規範前端JavaScript
- 前端規範之CSS規範前端CSS
- 前端規範之HTML 規範前端HTML
- SMB/CIFS協議解析(一)協議
- RTSP協議、RTMP協議、HTTP協議的區別協議HTTP
- 桌面管理系統協助規範日常運維工作運維
- 【網路協議】UDP協議協議UDP
- 資料庫操作規範及SQL書寫建議資料庫SQL