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"中,每個相關的值都潛在的以名,序數或這兩者來區分。這叫作"accessor"。復合值的例子有定單和股票報表等等。數組也是復合值。在復合值中,多個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值最好不要這樣表示(也可以這樣表示)。 對于每個具有值的元素,值的類型時必須用下述三種方式之一描述:(a)所屬元素實例有xsi:type屬性 (b)所屬元素是一個有SOAP-ENC:arrayType 屬性(該屬性可能是缺省的)的元素的子元素,或者(c)所屬元素的名具有特定的類型,類型可以由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:arrayType中引用的類型必須是每個數組成員的類型或超類型)。在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允許獨立的元素和數組成員名不同于值類型的元素。
5.2 簡單類型 SOAP采用了"XML Schema Part 2: Datatypes"規范[11]"Built-in datatypes"節中的所有類型作為簡單類型,包括值和取值范圍。例如:
類型舉例 int 58502 float 314159265358979E+1 negativeInteger-32768 string Louis "Satchmo" Armstrong
在XML Schema規范中聲明的數據類型可以直接用在元素schema中,也可以使用從這些類型衍生的新類型。一個schema和對應的具有這些類型的元素的數據實例的例子如下所示:
<element name="age" type="int"/> <element name="height" type="float"/> <element name="displacement" type="negativeInteger"/> <element name="color"> <simpleType base="xsd:string"> <enumeration value="Green"/> <enumeration value="Blue"/> </simpleType> </element>
<age>45</age> <height>5.9</height> <displacement>-450</displacement> <color>Blue</color>
所有簡單值必須編碼為元素的內容,它的類型或者在"XML Schema Part 2: Datatypes"規范[11]中定義過,或者是基于一個用XML Schema規范提供的機制能推衍生出的類型。
如果一個簡單值編碼為獨立元素或異質數組成員,那么有一個對應于數據類型的元素聲明將會很方便。因為"XML Schema Part 2: Datatypes"規范[11]包括了類型定義,但是不包括對應的元素聲明,SOAP-ENC schema和名域為每個簡單數據類型聲明了一個元素,如
<SOAP-ENC:int id="int1">45</SOAP-ENC:int> 5.2.1 字符串 字符串數據類型的定義在"XML Schema Part 2: Datatypes"規范[11]中。注意,這不同于許多數據庫和程序語言中的"string"類型,特別的,字符串數據類型可能禁止某些在那些語言中允許的字符。(這些值必須用xsd:string之外的數據類型表示)
一個字符串可能編碼為一個single-reference 或 multi-reference值。
包含字符串值的元素可能有一個"id"屬性。附加的accessor元素可能有對應的"href"屬性。
例如,同一字符串的兩個accessor可能以如下形式出現:
<greeting id="String-0">Hello</greeting> <salutation href="#String-0"/> 但是,如果兩個accessor參考同一字符串實例(或字符串的子類型),這不是一個實質問題,它們可以編碼為兩個single-reference值,如下所示:
<greeting>Hello</greeting> <salutation>Hello</salutation> 這個例子的schema片斷如下所示:
<element name="greeting" type="SOAP-ENC:string"/> <element name="salutation" type="SOAP-ENC:string"/>
在這個例子中,SOAP-ENC:string類型用作元素的類型,這是聲明數據類型是"xsd:string"且允許"id" 和"href"屬性的元素的簡便方法。精確定義參見SOAP編碼schema。Schemas可以使用這些源自SOAP編碼schema的聲明,但也可以不這樣做。
5.2.2 Enumerations "XML Schema Part 2: Datatypes"規范 [11] 定義了"enumeration."機制。SOAP數據模型直接采用了這種機制。但是,由于程序語言和其它語言在定義枚舉時通常有些不同,所以我們在這里詳細闡述了它的概念并描述了一個列表成員的可能取的值是如何編碼的。
"Enumeration"作為一個概念表示不同的名字的集合。一個特定的枚舉就是對應于特定的基類型的不同的值的列表。例如,顏色集合("Green", "Blue", "Brown")可以定義為基于字符串類型的枚舉,("1", "3", "5")可能是一個基于整型數的枚舉,等等。"XML Schema Part 2: Datatypes" [11]支持除了布爾型以外所有簡單類型的枚舉。"XML Schema Part 1: Structures"規范[10]的語言可以用來定義枚舉類型。如果schema由另一個沒有特定基類型適用的符號系統生成,就使用"string"。在下面schema的例子中,"EyeColor"定義為字符串,可能的值是"Green", "Blue", 或"Brown"的枚舉,數據實例按照schema顯示如下。
<element name="EyeColor" type="tns:EyeColor"/> <simpleType name="EyeColor" base="xsd:string"> <enumeration value="Green"/> <enumeration value="Blue"/> <enumeration value="Brown"/> </simpleType>
<Person> <Name>Henry Ford</Name> <Age>32</Age> <EyeColor>Brown</EyeColor> </Person>
5.2.3 字符數組 一個字符數組可能編碼為single-reference 或multi-reference值。字符數組的編碼規則與字符串的編碼規則類似。
特別的,包含字符數組的元素值可能由一個"id"屬性,附加的accssor元素可能有相應的"href"屬性。
推薦使用定義在XML Schemas [10][11]中的'base64'編碼(使用在2045 [13]中定義的base64編碼算法)表示模糊字符數組。不過,由于行長度(line length)的限制,通常在MIME中應用base64編碼,SOAP中一般不應用base64編碼。但是提供了"SOAP-ENC:base64"子類型使之能用于SOAP。
<picture xsi:type="SOAP-ENC:base64"> aG93IG5vDyBicm73biBjb3cNCg== </picture>
5.3 多態accessor 許多語言允許能夠多態訪問多種類型值的accessor,每種類型在運行時可用。一個多態accessor實例必須包含一個"xsi:type"屬性描述實際值的類型。
例如,一個名為"cost"類型值為"xsd:float"的多態accessor編碼如下:
<cost xsi:type="xsd:float">29.95</cost> 與之對比,類型值不變的accessor編碼如下:
<cost>29.95</cost> 5.4 Compound types復合類型 SOAP定義了與下列常在程序語言中出現的結構性模式對應的類型:
結構 一個"struct"是一個復合值,它的成員值的唯一區別是accessor名稱,任意兩個accessor名稱都不相同。 數組 一個"array"是一個復合值,它的成員值的唯一區別是序數位置。 SOAP也允許結構和數組之外的其它數據的序列化,例如Directed-Labeled-Graph Data Model之類的數據中,單個節點有許多不同的accssor,有些不止出現一次。SOAP序列化規則不要求底層的數據模型在accssor之間區分次序,但如果有這樣的次序的話,這些accssor必須按照這個順序編碼。
5.4.1 復合值,結構和值引用 復合值的成員編碼為accessor元素。當accessor由名區分時(如結構),accessor名即作為元素名。名局部于類型的accessor有不受限的名,其它的accessor則有受限的名。
下面的例子是類型為"Book"的結構:
<e:Book> <author>Henry Ford</author> <preface>Prefatory text</preface> <intro>This is a book.</intro> </e:Book>
以下是描述上面結構的schema片斷:
<element name="Book"> <complexType> <element name="author" type="xsd:string"/> <element name="preface" type="xsd:string"/> <element name="intro" type="xsd:string"/> </complexType> </e:Book>
|