5. SOAP编码SOAP编码风格是基于一个简单类型系统,而这个系统是程序语言、数据库和半结构数据中类型系统的公共特性的泛化。一个类型要么是一个简单(可量化的)类型或是一个复合类型,这个复合类型由多个部分组成,每个部分是一个类型。下面会有类型的更为详细的描述。本节定义了一个编序规则,用于可类型化对象图的编序。它在两个级别上操作。首先,给出一个符号上一致化的由该类型系统描述的模式,构造一个XML语法层的模式。其次,提供一个类型系统的模式以及一个与该模式相一致的值的表示方法,构造一个XML实例层的模式。反之,先提供一个符合这些规则XML实例,然后再给出原始的模式、一个原始值表示,也是可以构造的。
在本节中定义的元素和属性所用到的命名空间标识是"http://www.w3.org/2001/06/soap-encoding"。而这些编码的例子中假定所有命名空间声明都是在更高的元素层次上。
在本节中描述的数据模型和编码风格的使用方式是被鼓励的而不是必备的,其他的数据模型和编码也是可以与SOAP联合使用的(参阅 section 4.1.1)。
5.1 使用XML进行类型编码的规则XML允许非常柔性地编码数据。SOAP只定义了非常有限的编码规则。本节在一个高层次上定义编码规则,而下一节则描述明确类型的编码规则,当有更细节的需求的时候。本节中描述的编码可以与Section 7中描述的RPC调用和响应的映射联合使用。
为了描述编码,以下术语将被使用:
编序规则如下:
SOAP数组有一或多维,而它的成员由顺序位置区分。一个数组的值被表示为一序列反映该数组的元素,这些成员按序数从小到大顺序出现。对于多维数组,则元素维按从右到左顺序变化。没一个成员元素都被命名为一个独立元素(参阅 rule 2)。
SOAP数组可以是单引用值,也可以是多引用值,从而可以被表示为一个嵌入元素或一个独立元素。
SOAP数组必须包含一个“enc:arrayType”属性,其中定义的包含元素的值的类型与维数一起描述了该数组。”enc:arrayType”属性的值定义如下:
“asize”结构包含一个由逗号分隔的由零个、一个或多个整数组成的序列指明的数组的每个维的长度。一个由零个整数组成的序列表明对数组打下并没有特别限制,不过具体的大小将由下层具体的成员来决定。
例如,一个有5个成员的数组,成员类型为integer数组,它的arrayTypeValue的值就应当是 “int[][5]”。其中,atype的值是“int[]”,asize的值是“[5]”。类似地,一个有3个成员的数组,成员类型为integer二维数组,它的arrayTypeValue的值就应当是 “int[,][3]”。其中,atype的值是“int[,]”,asize的值是“[3]”。
SOAP数组成员可以包含一个“enc:offset”属性来指明该成员在其装载的数组中的偏移量。这也可以用于指明在一个部分描述的数组中成员的偏移(参阅 section 5.4.2.1)。类似的,SOAP数组成员可以包含一个“enc:position”属性来指明该成员在其装载的数组中的位置。这也可以用于指明在一个稀疏描述的数组中成员的位置(参阅 section 5.4.2.2)。“enc:offset”和“enc:position”属性的值定义为:
他们的基数都是0。
5.2 简单类型对于简单类型,SOAP采用了在“XML Schema Part 2: Datatypes”[11]的“Build-in datatypes”节中定义的所有类型,包括值和词汇空间(lexical spaces)。例子包括:
TypeExample
在XML Schema规范中声明的数据类型可以直接在元素模式中使用。而源于这些类型的类型也可以被使用。下面是一个模式片段和相应类型元素数据的例子:
Example 7<!-- schema document --><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" > <xs:element name="age" type="xs:int" /> <xs:element name="height" type="xs:float" /> <xs:element name="displacement" type="xs:negativeInteger" /> <xs:element name="color" > <xs:simpleType base="xsd:string"> <xs:restriction base="xs:string" > <xs:enumeration value="Green"/> <xs:enumeration value="Blue"/> </xs:restriction> </xs:simpleType> </xs:element></xs:schema>
Schema with simple types以下是一些合法的元素实例:
Example 8<!-- Example instance elements --><age>45</age><height>5.9</height><displacement>-450</displacement><color>Blue</color>
Message fragment corresponding to the schema in Example 7无论简单值类型是在“XML Schema Part 2: Datatypes”规范[11]中定义,还是基于XML Schema规范所提供的类型定义机制,都必须被编码为元素的内容。
如果一个简单值被编码为一个独立元素或一个异构数组的元素,这就很方便有一个对应于数据类型的元素声明。因为“XML Schema Part 2: Datatypes”规范[11]中包含了类型定义,但没有包含对应元素的声明,而enc模式和命名空间为每个简单数据类型声明了一个元素。这些是可以被使用的。
Example 9<enc:int xmlns:enc="http://www.w3.org/2001/06/soap-encoding" id="int1">45</enc:int>
5.2.1 字符串“string”数据类型在“XML Schema Part 2: Datatypes”[11]中被定义。值得注意的是在许多数据库或编程语言中,“string”类型并不是一致的,在某些特别的语言中,可能只允许一些字符能出现在“string”中。(这些值可能需要表示为xsd:string之外的一些数据类型)
一个字串可以被编码为一个单引用或多引用值。
包含string值的元素可以有一个“id”属性。额外的存取标识元素可以有匹配它的“href”属性。
例如,如果有两个对同一string的存取标识出现,则可以表现为:
Example 10<greeting id="String-0">Hello</greeting><salutation href="#String-0"/>
Two accessors for the same string无论如何,事实上对一个string(或者是string的子类型)的实例加以两个引用与将他们编码成两个单引用值并没有本质的区别:
Example 11<greeting>Hello</greeting><salutation>Hello</salutation>
Two accessors for the same string对于这些例子的模式描述可能是:
Example 12<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" > <xs:import namespace="http://www.w3.org/2001/06/soap-encoding" /> <xs:element name="greeting" type="enc:string" /> <xs:element name="salutation" type="enc:string" /></xs:schema>
Schema for Example 11(在这个例子中,用于描述元素类型的enc:string类型是一个方便的方法,来描述一个元素的类型是“xsd:string”,并且它可以附带“id” 和“href”属性。可以参阅SOAP Encoding模式来得到确切的定义。模式也可以使用这些SOAP Encoding模式中的声明,但不是必须的。)
5.2.2 枚举“XML Schema Part 2: Datatypes”规范[11]定义了一种称为“玫举(enumeration)”的机制。SOAP数据模型直接采用了这个机制。可是,由于编程语言及其他语言在定义玫举上存在着一些细微的差别,因此我们在这里描述了更详细的概念,并描述了如何将一个成为玫举列表成员的值进行编码。具体的,它编码为该值的名。
在概念上,“玫举”表示了一组不同的名。一个具体的玫举是一个符合基本类型的不同值的具体列表。例如,颜色名(“Green”, “Blue”, “Brown”)的集合可以被定义为一个基于内置string类型的玫举, 值(“1”, “3”, “5”)则可能是一个基于integer的玫举,等等。“XML Schema Part 2: Datatypes”规范[11]支持除boolean外所有简单类型的玫举。“XML Schema Part 2: Structures”规范[10]语言可以用于定义玫举类型。如果一个模式是从另一种符号体系生成过来而没有具体的基本类型可应用,那么就使用“string”。在下面的模式例子“EyeColor”被定义为一个string的玫举,其可能的值包括“Green”、“Blue”、“Brown”,同时实例数据也对应地给出了。
Example 13<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://example.org/2001/06/samples" targetNamespace="http://example.org/2001/06/samples" > <xs:element name="EyeColor" type="tns:EyeColor" /> <xs:simpleType name="EyeColor" > <xs:restriction base="xs:string" > <xs:enumeration value="Green" /> <xs:enumeration value="Blue" /> <xs:enumeration value="Brown" /> </xs:restriction> </xs:simpleType></xs:schema>
Schema with enumeration
Example 14<p:EyeColor xmlns:p="http://example.org/2001/06/samples" >Brown</p:EyeColor>
Message fragment corresponding to the schema in Example 135.2.3 字节数组一个Byte数组可以编码为单引用或多引用值。Byte数组的编码规则与string是类似的。
特别的,包含Byte数组值的元素可以有一个“id”属性。额外的存取标识元素可以有一个用于匹配的“href”属性。
对一个不透明的Byte数组的推荐表示是使用在XML Schema规范[10][11]中定义的“base64”编码方式,具体编码算法是在RFC 2045[13]中定义。不过,MIME中base64编码数据的数据行长度限制在SOAP中将不存在。SOAP中应使用“enc:base64”子类型来定义base64编码。
Example 15<picture xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" xsi:type="enc:base64" > aG93IG5vDyBicm73biBjb3cNCg==</picture>
Image with base64 encoding5.3 多态存取标识许多语言允许存取标识可以多态地访问数个类型的值,在运行时刻每个类型都是可使用的。一个多态存取标识实例必须包含一个“xsi:type”属性以描述类型的实际值。
例如,一个名为“cost”带有类型为“xsd:float”的值的多态存取标识可以编码为:
Example 16<cost xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:float">29.95</cost>
Polymorphic accessor与之相对的是一个值类型不变的cost存取标识。
Example 17<cost>29.95</cost>
Accessor whose value type is invariant5.4 复合类型SOAP依照在程序语言中常常看见的以下结构模式来定义复合类型:
Struct “struct”是一个复合类型值,其成员的存取标识名是相互区别的唯一标志,应彼此各不相同。
Array “array”是一个复合类型值,其成员的顺序位置是相互区别的唯一标志。
SOAP也允许数据的编序即不是Struct也不是Array,例如在Directed-Labeled-Graph数据模型中单个数据结点有很多不同的存取标识,其中有些会出现多次。SOAP遍序并不需要下层的数据模型要区别存取标识的次序区别,但如果有这种次序存在的话,那么存取标识必须按照该次序编码。
5.4.1 复合值及对值的引用复合值的成员被编码为存取标识元素。存取标识由他们的名字来相区别(例如在struct里面),而元素名就是存取标识名。存取标识名是局部的,作用域是包含他们的类型中,具备一个未修饰的元素名,而其他则有完全修饰名。
下面是一个“Book”结构的例子:
Example 18<e:Book xmlns:e="http://example.org/2001/06/books" > <author>Henry Ford</author> <preface>Prefactory text</preface> <intro>This is a book.</intro></e:Book>
Book structure下面则是一个描述该结构的模式片段:
Example 19<xs:element name="Book" xmlns:xs='http://www.w3.org/2001/XMLSchema' > <xs:complexType> <xs:sequence> <xs:element name="author" type="xs:string" /> <xs:element name="preface" type="xs:string" /> <xs:element name="intro" type="xs:string" /> </xs:sequence> </xs:complexType></xs:element>
Schema for Example 18下面是一个即包含简单类型成员也包含复合类型成员的类型的例子。它显示了两层的引用。注意“Author”存取标识元素的“href”属性一个对匹配“id”值对应的值的引用。“Address”中的情况也是类似的。
Example 20<e:Book xmlns:e="http://example.org/2001/06/books" > <title>My Life and Work</title> <author href="#Person-1"/></e:Book><e:Person xmlns:e="http://example.org/2001/06/books" id="Person-1" > <name>Henry Ford</name> <address href="#Address-2"/></e:Person><e:Address xmlns:e="http://example.org/2001/06/books" id="Address-2" > <email>mailto:henryford@hotmail.com</email> <web>http://www.henryford.com</web></e:Address>
Book with muli-reference addresses当“Person”和“Address”的值是需要多引用的时候,上述描述是合适的。如果使用单引用来描述,则应该是嵌入的,如下:
Example 21<e:Book xmlns:e="http://example.org/2001/06/books" > <title>My Life and Work</title> <author> <name>Henry Ford</name> <address> <email>mailto:henryford@hotmail.com</email> <web>http://www.henryford.com</web> </address> </author></e:Book>
Book with single-reference addresses如果这里存在着一个限制:在一个给出的实例中不允许有两个人有同样的地址,地址可以是一个街道地址(Street-address),也可以是一个电子地址(Electronic-address)。一本有两个作者的书可以编码为:
Example 22<e:Book xmlns:e="http://example.org/2001/06/books" > <title>My Life and Work</title> <firstauthor href="#Person-1"/> <secondauthor href="#Person-2"/></e:Book><e:Person xmlns:e="http://example.org/2001/06/books" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Person-1" > <name>Henry Ford</name> <address xsi:type="e:ElectronicAddressType"> <email>mailto:henryford@hotmail.com</email> <web>http://www.henryford.com</web> </address></e:Person><e:Person xmlns:e="http://example.org/2001/06/books" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Person-2"> <name>Samuel Crowther</name> <address xsi:type="e:StreetAddressType"> <street>Martin Luther King Rd</street> <city>Raleigh</city> <state>North Carolina</state> </address></e:Person>
Book with two authors having different addresses编序也可以包含一些不在同一资源中的值的引用:
Example 23<e:Book xmlns:e="http://example.org/2001/06/books" > <title>Paradise Lost</title> <firstAuthor href="http://www.dartmouth.edu/~milton/" /></e:Book>
Book with external references同时下面是一个对上面结构的模式描述片段:
Example 24<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://example.org/2001/06/books" targetNamespace="http://example.org/2001/06/books" > <xs:element name="Book" type="tns:BookType" /> <xs:complexType name="BookType" > <xs:annotation> <xs:documentation> <info> Either the following group must occur or else the href attribute must appear, but not both. </info> </xs:documentation> </xs:annotation> <xs:sequence minOccurs="0" maxOccurs="1" > <xs:element name="title" type="xs:string" /> <xs:element name="firstAuthor" type="tns:PersonType" /> <xs:element name="secondAuthor" type="tns:PersonType" /> </xs:sequence> <xs:attribute name="href" type="xs:anyURI" /> <xs:attribute name="id" type="xs:ID" /> <xs:anyAttribute namespace="##other" /> </xs:complexType> <xs:element name="Person" type="tns:PersonType" /> <xs:complexType name="PersonType" > <xs:annotation> <xs:documentation> <info> Either the following group must occur or else the href attribute must appear, but not both. </info> </xs:documentation> </xs:annotation> <xs:sequence minOccurs="0" maxOccurs="1" > <xs:element name="name" type="xs:string" /> <xs:element name="address" type="tns:AddressType" /> </xs:sequence> <xs:attribute name="href" type="xs:anyURI" /> <xs:attribute name="id" type="xs:ID" /> <xs:anyAttribute namespace="##other" /> </xs:complexType> <xs:element name="Address" base="tns:AddressType" /> <xs:complexType name="AddressType" abstract="true" > <xs:annotation> <xs:documentation> <info> Either one of the following sequences must occur or else the href attribute must appear, but not both. </info> </xs:documentation> </xs:annotation> <xs:choice> <xs:sequence minOccurs="0" maxOccurs="1" > <xs:element name="email" type="xs:string" /> <xs:element name="web" type="xs:anyURI" /> </xs:sequence> <xs:sequence minOccurs='0' maxOccurs='1' > <xs:element name="street" type="xs:string" /> <xs:element name="city" type="xs:string" /> <xs:element name="state" type="xs:string"/> </xs:sequence> </xs:choice> <xs:attribute name="href" type="xs:anyURI"/> <xs:attribute name="id" type="xs:ID"/> <xs:anyAttribute namespace="##other"/> </xs:complexType> <xs:complexType name="StreetAddressType"> <xs:annotation> <xs:documentation> <info> Either the second sequence in the following group must occur or else the href attribute must appear, but not both. </info> </xs:documentation> </xs:annotation> <xs:complexContent> <xs:restriction base="tns:AddressType" > <xs:sequence> <xs:sequence minOccurs="0" maxOccurs="0" > <xs:element name="email" type="xs:string" /> <xs:element name="web" type="xs:anyURI" /> </xs:sequence> <xs:sequence minOccurs="0" maxOccurs="1"> <xs:element name="street" type="xs:string" /> <xs:element name="city" type="xs:string" /> <xs:element name="state" type="xs:string"/> </xs:sequence> </xs:sequence> <xs:attribute name="href" type="xs:anyURI"/> <xs:attribute name="id" type="xs:ID"/> <xs:anyAttribute namespace="##other"/> </xs:restriction> </xs:complexContent> </xs:complexType> <xs:complexType name="ElectronicAddressType"> <xs:annotation> <xs:documentation> <info> Either the first sequence in the following group must occur or else the href attribute must appear, but not both. </info> </xs:documentation> </xs:annotation> <xs:complexContent> <xs:restriction base="tns:AddressType" > <xs:sequence> <xs:sequence minOccurs="0" maxOccurs="1"> <xs:element name="email" type="xs:string" /> <xs:element name="web" type="xs:anyURI" /> </xs:sequence> <xs:sequence minOccurs="0" maxOccurs="0"> <xs:element name="street" type="xs:string" /> <xs:element name="city" type="xs:string" /> <xs:element name="state" type="xs:string"/> </xs:sequence> </xs:sequence> <xs:attribute name="href" type="xs:anyURI"/> <xs:attribute name="id" type="xs:ID"/> <xs:anyAttribute namespace="##other"/> </xs:restriction> </xs:complexContent> </xs:complexType></xs:schema>
Schema for example 225.4.2 数组SOAP数组被定义为类型为“enc:Array”或类型源于“enc:Array”(可参阅 rule 8)。这种类型源于"enc:Array"的类型必须遵从"enc:Array"的限制,同时它可用于表示以下情况的类型定义,譬如整型数的数组或是一些用户自定义的枚举类型的数组等。数组被表示为对包含其的元素的名无特殊约束的元素值(就象值一般不会约束包含元素的名)。组成数组的元素可以是任意类型,包括嵌套的数组。
数组值的表示是一个该数组组成元素的一个有序序列。作为一个数组的值,元素名对于区分存取标识并非重要。元素可以有任意的名。实际上,这些元素的命名将按照模式中声明的建议,或由他们的类型所决定。就象在复合类型中通常情况下,如果数组中条目的值是单引用值,则该条目将包含它的值。否则,条目通过“href”属性引用它的值。
下面是一个模式的片段以及一个包含integer成员的数组:
Example 25<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" > <xs:import namespace="http://www.w3.org/2001/06/soap-encoding" /> <xs:element name="myFavoriteNumbers" type="enc:Array" /></xs:schema>
Schema declaring an array of integers
Example 26<myFavoriteNumbers xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" enc:arrayType="xs:int[2]" > <number>3</number> <number>4</number></myFavoriteNumbers>
Array conforming to the schema in Example 25在这个例子中,“myFavoriteNumber”数组包含了几个成员,每个成员的值的类型都是xs:int。而类型是由enc:arrayType属性决定的。注意enc:Array的类型允许不严格的未修饰的元素名。这些名只传输了非类型的信息,因此在具体使用的时候,要么有一个xsi:type属性,要么包含它的元素要包含一个enc:arrayType属性。自然地,源于enc:Array的类型可以声明带类型信息的局部元素。
就象先前指出的,enc模式包含了一些元素名的声明,而这些名是对应于“XML Schema Part 2: Datatypes”规范[11]中的每个简单类型的。这也包含一个“Array”的声明。使用这些定义,我们也许可以将显现先前的描述改写为:
Example 27<enc:Array xmlns:enc="http://www.w3.org/2001/06/soap-encoding" xmlns:xs="http://www.w3.org/2001/XMLSchema" enc:ArrayType="xs:int[2]" > <enc:int>3</enc:int> <enc:int>4</enc:int></enc:Array>
Using the enc:Array element数组可以包含任意指定arrayType的子类型的实例。也就是说,成员的类型可以是任何描述在arrayType属性中类型的可替代类型,这将依照于在模式中表示的可替代规则。因此,例如,一个整数数组可以包含任何源于integer的类型的值(例如 “int”或任何用户定义的源于integer的类型)。类似的,一个“address”数组可以包含一个严格的或扩展的类型,比如“internationalAddress”。因为提供的enc:Array类型允许包含任何类型或类型混合的成员,除非有对arrayType属性使用的特别限制。
成员元素类型在实例中可以使用xsi:type来描述,或则是在成员元素模式中声明,就象在下面两个数组中分别演示的那样:
Example 28<enc:Array xmlns:enc="http://www.w3.org/2001/06/soap-encoding" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" enc:arrayType="xs:anyType[4]"> <thing xsi:type="xs:int">12345</thing> <thing xsi:type="xs:decimal">6.789</thing> <thing xsi:type="xs:string"> Of Mans First Disobedience, and the Fruit Of that Forbidden Tree, whose mortal tast Brought Death into the World, and all our woe, </thing> <thing xsi:type="xs:anyURI"> http://www.dartmouth.edu/~milton/reading_room/ </thing></enc:Array>
Array with elements of varying types
Example 29<enc:Array xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" enc:arrayType="xs:anyType[4]" > <enc:int>12345</enc:int> <enc:decimal>6.789</enc:decimal> <enc:string> Of Mans First Disobedience, and the Fruit Of that Forbidden Tree, whose mortal tast Brought Death into the World, and all our woe, </enc:string> <enc:anyURI> http://www.dartmouth.edu/~milton/reading_room/ </enc:anyURI ></enc:Array>
Array with elements of varying types数组值可以是结构或其他复合值。例如一个“xyz:Order”结构的数组:
Example 30<enc:Array xmlns:enc="http://www.w3.org/2001/06/soap-encoding" xmlns:xyz="http://example.org/2001/06/Orders" enc:arrayType="xyz:Order[2]"> <Order> <Product>Apple</Product> <Price>1.56</Price> </Order> <Order> <Product>Peach</Product> <Price>1.48</Price> </Order></enc:Array>
Arrays containing structs and other compound values数组也可以有一些成员值是数组。下面是一个有两个数组的数组的例子,而那两个数组都是string数组:
Example 31<enc:Array xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" enc:arrayType="xs:string[][2]" > <item href="#array-1"/> <item href="#array-2"/></enc:Array><enc:Array xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" id="array-1" enc:arrayType="xs:string[2]"> <item>r1c1</item> <item>r1c2</item> <item>r1c3</item></enc:Array><enc:Array xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" id="array-2" enc:arrayType="xs:string[2]"> <item>r2c1</item> <item>r2c2</item></enc:Array>
Array containing other arrays包含一个数组值的元素并不需要一定被命名为“enc:Array”。它可以有任意的名,而提供的类型则要么是enc:Array,要么是受源于enc:Array的限制。例如,下面是一个模式片段以及与之一致的一个实例数组:
Example 32<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" xmlns:tns="http://example.org/2001/06/numbers" targetNamespace="http://example.org/2001/06/numbers" > <xs:simpleType name="phoneNumberType" > <xs:restriction base="xs:string" /> </xs:simpleType> <xs:element name="ArrayOfPhoneNumbers" type="tns:ArrayOfPhoneNumbersType" /> <xs:complexType name="ArrayOfPhoneNumbersType" > <xs:complexContent> <xs:restriction base="enc:Array" > <xs:sequence> <xs:element name="phoneNumber" type="tns:phoneNumberType" maxOccurs="unbounded" /> </xs:sequence> <xs:attributeGroup ref="enc:arrayAttributes" /> <xs:attributeGroup ref="enc:commonAttributes" /> </xs:restriction> </xs:complexContent> </xs:complexType></xs:schema>
Schema for an array
Example 33<abc:ArrayOfPhoneNumbers xmlns:abc="http://example.org/2001/06/numbers" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" enc:arrayType="abc:phoneNumberType[2]" > <phoneNumber>206-555-1212</phoneNumber> <phoneNumber>1-888-123-4567</phoneNumber></abc:ArrayOfPhoneNumbers>
Array conforming to the schema in Example 32数组可以是多维的。在这种情况下,就会有多个描述维数大小的值出现在arrayType属性的asize部分:
Example 34<enc:Array xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" enc:arrayType="xs:string[2,3]" > <item>r1c1</item> <item>r1c2</item> <item>r1c3</item> <item>r2c1</item> <item>r2c2</item> <item>r2c3</item></enc:Array>
Multi-dimensonal array上述例子中显示了一个数组如何被编码为独立元素,数组值可以以嵌套方式出现并且如果他们是单引用的话,应该使用这种方式。
下面是一个模式片段的例子以及符合该模式的一个嵌套在“Person”结构中的电话号码数组,该数组可以从存取标识“phone-numbers”访问:
Example 34<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" xmlns:tns="http://example.org/2001/06/numbers" targetNamespace="http://example.org/2001/06/numbers" > <xs:import namespace="http://www.w3.org/2001/06/soap-encoding" /> <xs:simpleType name="phoneNumberType" > <xs:restriction base="xs:string" /> </xs:simpleType> <xs:element name="ArrayOfPhoneNumbers" type="tns:ArrayOfPhoneNumbersType" /> <xs:complexType name="ArrayOfPhoneNumbersType" > <xs:complexContent> <xs:restriction base="enc:Array" > <xs:sequence> <xs:element name="phoneNumber" type="tns:phoneNumberType" maxOccurs="unbounded" /> </xs:sequence> <xs:attributeGroup ref="enc:arrayAttributes" /> <xs:attributeGroup ref="enc:commonAttributes" /> </xs:restriction> </xs:complexContent> </xs:complexType> <xs:element name="Person"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string" /> <xs:element name="phoneNumbers" type="tns:ArrayOfPhoneNumbersType" /> </xs:sequence> </xs:complexType> </xs:element></xs:schema>
Schema fragment for array of phone numbers embedded in a struct
Example 35<def:Person xmlns:def="http://example.org/2001/06/numbers" xmlns:enc="http://www.w3.org/2001/06/soap-encoding" > <name>John Hancock</name> <phoneNumbers enc:arrayType="def:phoneNumber[2]"> <phoneNumber>206-555-1212</phoneNumber> <phoneNumber>1-888-123-4567</phoneNumber> </phoneNumbers></def:Person>
Array of phone numbers embedded in a struct conforming to the schema in Example 34下面是单引用数组值的另一个例子,数组值被编码为嵌入元素,这些元素都包含作为存取标识的元素名:
Example 36<xyz:PurchaseOrder xmlns:xyz="http://example.org/2001/06/Orders" > <CustomerName>Henry Ford</CustomerName> <ShipTo> <Street>5th Ave</Street> <City>New York</City> <State>NY</State> <Zip>10010</Zip> </ShipTo> <PurchaseLineItems xmlns:enc="http://www.w3.org/2001/06/soap-encoding" enc:arrayType="xyz:Order[2]"> <Order> <Product>Apple</Product> <Price>1.56</Price> </Order> <Order> <Product>Peach</Product> <Price>1.48</Price> </Order> </PurchaseLineItems></xyz:PurchaseOrder>
Single-reference array encoded as en embedded element5.4.2.1 部分传输数组SOAP提供对部分传递数组的支持,这就象在一些上下文[12]中的“可变长”数组。一个部分传递数组应使用“enc:offset”属性标识,该属性的记数是以第一元素的位移为0开始的。如果省略该属性,则位移默认是0。
下面是一个大小为5的数组,同时在传递的时候仅传递第三和第四个元素:
Example 37<enc:Array xmlns:enc="http://www.w3.org/2001/06/soap-encoding" xmlns:xs="http://www.w3.org/2001/XMLSchema" enc:arrayType="xs:string[6]" enc:offset="[3]" > <item>The fourth element</item> <item>The fifth element</item></enc:Array>
Array of size five that transmits only the third and fourth element5.4.2.2 稀疏数组SOAP提供对稀疏数组的支持。每一个表示成员值的元素包含一个“enc:position”属性来表明它处于数组的位置。下面是一个二维字串数组的稀疏数组的例子。他的大小是4,但仅有位置2被使用:
Example 38<enc:Array xmlns:enc="http://www.w3.org/2001/06/soap-encoding" xmlns:xs="http://www.w3.org/2001/XMLSchema" enc:arrayType="xs:string[,][4]" > <enc:Array href="#array-1" enc:position="[2]" /></enc:Array><enc:Array id="array-1" enc:arrayType="xs:string[10,10]" > <item enc:position="[2,2]">Third row, third col</item> <item enc:position="[7,2]">Eighth row, third col</item></enc:Array>
Sparse array如果在上述数组中对array-1仅有一个引用,那上述例子可以被编码为:
Example 39<enc:Array xmlns:enc="http://www.w3.org/2001/06/soap-encoding" xmlns:xs="http://www.w3.org/2001/XMLSchema" enc:arrayType="xs:string[,][4]" > <enc:Array enc:position="[2]" enc:arrayType="xs:string[10,10]" > <item enc:position="[2,2]">Third row, third col</item> <item enc:position="[7,2]">Eighth row, third col</item> </enc:Array></enc:Array>
Another sparse array5.4.3 通用复合类型上面引用到的编码规则并不限于那些预先知道存取标识的情形。如果存取标识名仅当在编码过程中由值的出现才能决定的时候,同样的规则也可以应用,也就是一个存取标识被编码为同名的元素,并且该存取标识要么包含要么引用它的值。包含那些类型不能预先决定的值的存取标识必须包含一个合适的xsi:type属性来给出值的类型。
类似的,引用的规则对于包含一些混合的存取标识的复合类型的编序而言已经足够了,这些存取标识有的是以名来区分,有的是以名和位置来区分 (也就是说,有些存取标识会重复出现) 。这并不一定需要有包含这一类型的模式存在,但是如果一个类型模型模式没有该类型时,那么一个对应的XML句法模式和实例就应该被生成。
Example 40<xyz:PurchaseOrder xmlns:xyz="http://example.org/2001/06/Orders" > <CustomerName>Henry Ford</CustomerName> <ShipTo> <Street>5th Ave</Street> <City>New York</City> <State>NY</State> <Zip>10010</Zip> </ShipTo> <PurchaseLineItems> <Order> <Product>Apple</Product> <Price>1.56</Price> </Order> <Order> <Product>Peach</Product> <Price>1.48</Price> </Order> </PurchaseLineItems></xyz:PurchaseOrder>
Generic compound types类似的,将一个复合类型值编序为类似数组结构的是合法的,但这不是enc:Array类型或其子类型。例如:
Example 41<PurchaseLineItems> <Order> <Product>Apple</Product> <Price>1.56</Price> </Order> <Order> <Product>Peach</Product> <Price>1.48</Price> </Order></PurchaseLineItems>
Compound value5.5 默认值一个省略格式的存取标识元素以为着有一个默认值或是尚不知道它的值。而该细节是基于存取标识、方法和上下文的。例如一个省略格式的存取标识典型地是表示一个多态存取标识的Null值(Null依赖存取标识的确切含义)。同样地,一个省略格式的Boolean存取标识典型地就意味着是一个False值或值未知,同时一个省略格式的数值存取标识典型地意味着它的值是0或值未知。
5.6 SOAP root属性SOAP root属性可以被用来标注编序的根,当然他并不是对象图真正的根,所以对象图是可以解序的。该属性可以赋予“0”和“1”这两个值的任意一个。一个对象图的真正的根一般就有值“1”。那些非真正根的编序根也可以被标注为赋予值为“1”的编序根。一个元素也可以被明确地标注为赋予值为“0”的非编序根。
SOAP根属性可以出现在SOAP Header和SOAP Body元素中的任何子元素里,该属性并没有一个默认值。