小咪儿的骚麦:SOAP Version 1.2中文手冊

来源:百度文库 编辑:偶看新闻 时间:2024/04/30 14:36:41

SOAP Version 1.2
W3C Working Draft 9 July 2001

英文版:
http://www.w3.org/TR/2001/WD-soap12-20010709/
英文版的最后版:
http://www.w3.org/TR/soap12/
英文版编辑:
Martin Gudgin (DevelopMentor)
Marc Hadley (Sun Microsystems)
Jean-Jacques Moreau (Canon)
Henrik Frystyk Nielsen (Microsoft Corp.)
 
中文版:
http://www.uddi-china.org/pubs/misc/soap12.htm
中文版编辑:
柴晓路, Fennivel Chai (DealEasy)
中文版贡献者:
许佑骏, Arthor Xu (DealEasy)
 
Copyright ©2001 W3C® (MIT, INRIA, Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply.




Abstract
SOAP 1.2为在一个松散的、分布的环境中使用XML对等地交换结构化的和类型化的信息提供了一个简单且轻量级的机制。这是一个基于XML的协议,同时它由四部分组成: 一个作为描述在消息中的内容以及如何处理消息的信息框架的信封(envelope),一组用于表示应用定义的数据类型的编码规则(encoding rules),一个用于表示远程过程调用和返回的约定以及一个使用底层协议进行消息交换的绑定(binding)约定。潜在地,SOAP可以与很多其他的协议绑定使用;不过,在本文档中,只定义了SOAP与HTTP已经SOAP与HTTP Extension Framework的绑定。


Status of this Document
This section describes the status of this document at the time of its publication. Other documents may supersede this document. The latest status of this document series is maintained at the W3C.


This is the first W3C Working Draft of the SOAP version 1.2 specification for review by W3C members and other interested parties. It has been produced by the XML Protocol Working Group (WG), which is part of the XML Protocol Activity.


The XML Protocol Protocol Working Group has, in keeping with its charter, produced a set of requirements and usage scenarios that have been published as a Working Draft. To better evaluate SOAP/1.1 against these requirements and usage scenarios, the Working Group has produced an abstract model and a glossary of terms and concepts used by the Working Group. In addition, the Working Group has produced an issues list that describes issues and concerns raised by mapping its requirements and the XMLP abstract model against the SOAP/1.1 specification as well as issues raised on the mailing list against SOAP/1.1.


The current name for this specification is SOAP version 1.2, this first Working Draft being based on SOAP/1.1 as per the Working Group‘s charter (see change log in appendix D)


Comments on this document should be sent to xmlp-comments@w3.org (public archives). It is inappropriate to send discussion emails to this address.


Discussion of this document takes place on the public mailing list (Archives) per the email communication rules in the XML Protocol Working Group Charter.


This is a public W3C Working Draft. It is a draft document and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use W3C Working Drafts as reference material or to cite them as other than "work in progress". A list of all W3C technical reports can be found at http://www.w3.org/TR/.


Table of Contents

                1. 引言
               

                    1.1 设计目标
                                        1.2 符号约定
                                        1.3 SOAP消息示例
                                        1.4 SOAP术语
                    

                        1.4.1 协议概念
                                                1.4.2 数据封装概念
                                                1.4.3 消息发送者和接收者概念
                                                1.4.4 数据编码概念
                     
                2. SOAP消息交换模型
               

                    2.1 SOAP结点
                                        2.2 SOAP角色与SOAP结点
                                        2.3 定位SOAP Header条目
                                        2.4 理解SOAP Header
                                        2.5 处理消息
                  
                3. 与XML的关系
                                4. SOAP信封
               



                        4.1.1 SOAP encodingStyle属性
                                                4.1.2 Envelope版本模型
                     
                    4.2 SOAP Header
                    

                        4.2.1 使用Header属性
                                                4.2.2 SOAP actor属性
                                                4.2.3 SOAP mustUnderstand属性
                        
                     
                    4.3 SOAP Body
                    

                        4.3.1 SOAP Header和Body的关系
                     
                    4.4 SOAP错误
                    

                        4.4.1 SOAP错误代码
                                                4.4.2 MustUnderstand错误
                     
                5. SOAP编码
               

                    5.1 使用XML进行类型编码的规则
                                        5.2 简单类型
                    

                        5.2.1 字符串
                                                5.2.2 枚举
                                                5.2.3 字节数组
                     
                    5.3 多态存取标识
                                        5.4 复合类型
                    

                        5.4.1 复合值及对值的引用
                                                5.4.2 数组
                        

                            5.4.2.1 部分传输数组
                                                        5.4.2.2 稀疏数组
                          
                        5.4.3 通用复合类型
                     
                    5.5 默认值
                                        5.6 SOAP root属性
                  
                6. 在HTTP中使用SOAP
               

                    6.1 SOAP HTTP请求
                    

                        6.1.1 HTTP Header中的SOAPAction字段
                     
                    6.2 SOAP HTTP响应
                                        6.3 HTTP扩展框架
                                        6.4 SOAP HTTP示例
                  
                7. 在RPC中使用SOAP
               

                    7.1 RPC和SOAP Body
                                        7.2 RPC和SOAP Header
                  
                8. 安全机制的考虑
                                9. 参考文献
               

                    9.1. Normative references
                                        9.2. Informative references
                    
                A. SOAP Envelope Examples
               

                    A.1 Sample Encoding of Call Requests
                                        A.2 Sample Encoding of Response
                  
                B. Acknowledgements
                                C. Version Transition From SOAP/1.1 to SOAP/1.2
                                D. Change Log
               

                    D.1 SOAP Specification Changes
                                        D.2 XML Schema Changes

1. 引言
            
SOAP
            v1.2为在一个松散的、分布的环境中使用XML对等地交换结构化的和类型化的信息提供了一个简单且轻量级的机制。SOAP本身并不定义任何应用语义,如编程模型或特定语义实现,它只是定义了一种简单的机制,通过一个模块化的包装模型和对模块中特定格式编码的数据的重编码机制来表示应用语义。SOAP的这项能力使得它可被很多类型的系统用于从消息系统到RPC(Remote
            Procedure Call)的延伸。
SOAP由四部分组成:
            
              
              
SOAP envelop (SOAP信封,参阅 section
              4),它构造定义了一个整体的表示框架,可用于表示在消息(message)中的是什么,谁应当处理它,以及这是可选的
              还是强制的。

              
              
SOAP encoding rules (SOAP编码规则,参阅 section
              5),定义了一个编序机制用于交换应用程序定义的数据类型的实例。

              
              
SOAP RPC representation (SOAP RPC表示,参阅 section
              7),定义了一个用于表示远端过程调用和响应的约定。

              
SOAP binding (SOAP绑定,参阅 section
              6) 定义了一个使用底层传输协议来完成在结点间交换SOAP信封的约定。

为了简化本规范,这四部分在功能上是正交的。特别的,信封和编码规则是被定义在不同的命名空间(namespace)中,这样有利于通过模块化获得简明性。
            
本规范还定义了两种SOAP绑定(binding),用于描述SOAP消息(message)如何通过带或不带HTTP扩展框架[6](HTTP
            Extension Framework)的HTTP[5]消息(message)进行传输。

            1.1 设计目标
            
SOAP的主要设计目标是简明性和可扩展性。这就意味着有一些传统消息系统或分布式对象系统中的特性将不包含在SOAP的核心规范中。这些特性包括:

            
              
              
分布式垃圾收集 (distributed garbage collection);

              
              
批量消息传输/处理 (boxcarring or batching of messages);

              
              
对象引用 (objects-by-reference, 需要分布式垃圾收集的支持);

              
              
对象激活 (activation, 需要对象引用的支持)。

            1.2 符号约定
            
本文中的关键词“MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
            “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”,
            “OPTIONAL”的语义应当参阅RFC-2119[2]。在本中文版规范中被翻译成:“必须”、“必须不”,“需要的”,“将”,“将不”,“应该”,“应该不”,“被推荐的”,“可以”,“可选的”。

            
本文中使用的命名空间前缀“env”和“enc”等关联的SOAP命名空间分别位于以下位置:"http://www.w3.org/2001/06/soap-envelope"
            和"http://www.w3.org/2001/06/soap-encoding"。

            
在本文的全部内容中,命名空间前缀"xs"和"xsi"总假定是与"http://www.w3.org/2001/XMLSchema"
            和"http://www.w3.org/2001/XMLSchema-instance"相关联的,这是由XML
            Schemas规范[10,11]所定义的。

            
值得注意的是其他的对命名空间前缀的使用都是比较随意的而并没有显著语义的约束的。

            
若命名空间的URI使用"http://example.org/..."或"http://example.com/..."的形式,表明这是一些应用依赖或上下文依赖的URI[4]。

            
本规范使用扩充BNF(Backus-Naur Form)作为构造语言,可参阅RFC-2612 [5]。

            
编辑的注解将使用黄色背景标识(也许无法在所有的媒介上显示),并使用前缀"Ednote"。

            1.3 SOAP消息示例
            
第一个例子展示了一个使用SOAP表示的简单的通知消息。该消息包含了一个消息头"alertcontrol"和消息体"alert",这两部分都是由应用程序定义的,而而并不是由SOAP定义的。消息头包含了两个参数"priority"和"expires",用于消息传输中介和消息接受者对消息的处理。而消息体中则包含是实际传送的消息。

            
            Example 0
            

  
   1
   2001-06-22T14:00:00-05:00
  


  
   Pick up Mary at school at 2pm
  


            Sample SOAP Message containing a header
            block and a body block
            
SOAP消息能够与不同的底层协议进行绑定,同时可以在很多种消息传输模式中使用。下面的例子则展示了SOAP是如何在HTTP的连接中使用的,其中充分使用了HTTP提供的请求/相应机制(参阅
            section
            6)。

            
Example 1和Example
            2展示了一个SOAP/HTTP请求的例子和一个SOAP/HTTP响应的例子。SOAP/HTTP请求包含了一个获取最后交易价格(GetLastTradePrice)的信息块,其中包含了一个简单的参数,指明需要报价的股票代号。同样,与先前的例子相似,GetLastTradePrice这个XML元素也并不是由SOAP自身定义的。该请求的服务响应也包含了一个简单的参数,股票的价格。SOAP信封元素是表示SOAP消息的XML文档的顶级元素。XML命名空间则用来消除SOAP标识符与应用定义的标识符之间可能存在的歧义。

            
            Example 1
            POST /StockQuote HTTP/1.1
Host: www.stockquoteserver.com
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "http://example.org/2001/06/quotes"



  
    DIS
  


            Sample SOAP Message embedded in an HTTP
            Request
            
Example 2展示了StockQuote服务响应由Example
            1描述的请求消息而返回的SOAP消息。

            
            Example 2
            HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn



  
   34.5
  


            Sample SOAP Message embedded in an HTTP
            Response
            
在Appendix
            A中提供了更多的例子。

            1.4 SOAP术语
            1.4.1 协议概念
            
              SOAP
              
              
关于SOAP消息的格式和处理规则、为沿着SOAP消息路径交换信息而需要的不同应用程序之间生成和接收SOAP消息的交互过程的简单控制机制等的一整套规范和约定。

              SOAP绑定
              
              
为传输的需要而将SOAP消息在另一个底层协议之上或之内传输的一整套规范和规则。典型的SOAP绑定包括在HTTP消息中传送SOAP消息或在TCP之上传送SOAP消息等。

              SOAP结点
              
              
SOAP结点根据SOAP定义的整套规范来处理SOAP消息。SOAP结点有责任遵守SOAP消息交换的规则以及提供通过依赖底层协议的SOAP绑定来访问的服务。任何不符合SOAP约定的情况都将导致SOAP结点产生一个SOAP错误(可参阅SOAP接受者和SOAP发送者)。

            1.4.2 数据封装概念
            
              SOAP消息
              
              
SOAP消息(message)是在对等SOAP结点(SOAP
              nodes)间通讯的基本单位。

              SOAP信封
              
              
SOAP信封(envelope)是SOAP规范中定义的SOAP消息(SOAP
              message)在句法上的最外层结构。在句法上,它包含了所有其他的元素。

              SOAP条目
              
              
SOAP条目是一个句法上的结构,它用于包含一个逻辑上的单一元素,这一元素是需要被SOAP结点处理的。一个SOAP条目是由该条目最外层元素的完整修饰名所标识的,这个完整修饰名是由一个局部名和一个命名空间URI组成的。封装在SOAP
              header中的SOAP条目成为Header条目,而封装在SOAP
              body中的SOAP条目为Body条目。

              SOAP header
              
              
能够被SOAP消息路径中任意的SOAP接受者处理的一组SOAP条目(0个或多个)。

              SOAP body
              
              
能够被SOAP消息路径中的最终SOAP接受者处理的一组SOAP条目(0个或多个)。

              SOAP fault
              
              
SOAP结点产生的用于包含错误信息的特殊的SOAP条目。

            
以下的图表演示了一个SOAP消息是如何组成的。

            Figure 1: Encapsulation model illustrating the
            parts of a SOAP message

            

            1.4.3 消息发送者和接收者概念
            
              SOAP发送者
              
              
SOAP发送者是发出SOAP消息的SOAP结点。

              SOAP接收者
              
              
SOAP接收者是接受SOAP消息的SOAP结点。

              SOAP消息路径
              
              
为传送一个简单的SOAP消息而要经过的一组SOAP发送者和SOAP接受者。其中包含了初始SOAP发送者、零个或多个SOAP中介以及最终SOAP接受者。

              初始SOAP发送者
              
              
SOAP消息的最初产生者,同时也是SOAP消息路径的第一个结点。

              SOAP中介
              
              
SOAP中介即是SOAP接收者也是SOAP发送者,是SOAP消息可到达的某一个应用程序。当SOAP消息沿着SOAP消息路径传输时,SOAP中介将处理一组确定的SOAP条目,然后它将消息转发给消息路径的下一个SOAP结点,直至传送到最终SOAP接收者。

              最终SOAP接收者
              
              
由初始SOAP发送者指定的通过SOAP消息路径传送SOAP消息的最终SOAP接收者。如果在SOAP消息路径中有SOAP结点产生了SOAP错误,那么SOAP消息将不会到达最终接收者。

            1.4.4 数据编码概念
            
              SOAP数据模型
              
              
一组抽象的构造约定,用于描述通用的数据类型和数据中的链接关系。

              SOAP数据编码
              
              
在SOAP消息中使用一个或多个SOAP条目,按照SOAP数据模型完成句法上的数据表示。

2. SOAP消息交换模型
从根本上来看,SOAP消息是从发送方到接受方的一种传输方法,但就象前面例子中阐述的那样,SOAP消息一般会和实现模式结合,例如请求/响应。


SOAP的实现可以为特殊网络系统的特有特征来优化。例如,在section 6中描述的HTTP binding将SOAP响应消息通过HTTP响应来传输,使用与相对应请求的同一HTTP连接。


2.1 SOAP结点

SOAP结点可以是初始SOAP发送者,可以是最终SOAP接收者,也可以是同时作为SOAP发送者和接收者的SOAP中介。SOAP并不提供一个路由机制,曾因此SOAP需要识别SOAP发送者产生的SOAP消息应当通过哪些零个或多个SOAP中介被发送到一个最终SOAP接收者。


接收到SOAP消息的SOAP结点必须能够实施处理、产生必要的SOAP错误和SOAP响应,如果合适的话还应当根据本规范的后续描述生成额外的SOAP消息。


2.2 SOAP角色与SOAP结点
当处理一个SOAP消息的时候,SOAP结点将被告知应当以一个或多个SOAP处理角色来处理,这些SOAP角色由SOAP actor名来标识,SOAP actor的名字是一个URI。每个SOAP结点都必须以一个指定的角色来处理,这个角色使用命名为"http://www.w3.org/2001/06/soap-envelope/actor/next"的SOAP actor来表示,同时可以按照需要应用零个或多个其他SOAP actor表示的额外角色。SOAP结点可以通过以匿名SOAP actor的角色来实施处理以使得自己成为最终SOAP接收者。当SOAP结点在处理一个SOAP消息的时候,其表现出的SOAP角色在整个处理过程中不得更改。这是因为本规范只涉及如何处理单个SOAP消息而无需考虑状态,因此是否允许在处理单个SOAP消息的时候转换角色是没有意义的。


SOAP actor名字是用来识别SOAP结点的,并没有与路由或者消息交换的语义相联系。举例来说,一个SOAP actor可以被命名为一个用来发送SOAP消息给适当SOAP结点的URI。相反,也有这样一些SOAP处理角色的名字,这些名字或者直接和消息路由相联系(例如,http://example.org/banking/anyAccountMgr),或者和路由没有联系(例如,当一个消息头被用来携带一个指示,该指示用来告知任何有关的软件该SOAP消息是长期不变的,是能够被安全的缓存和重用的,在这种SOAP消息头中,一个URI可以用于标识“所有缓存管理软件”),通过名字使用这些SOAP处理角色也是合适的。


2.3 定位SOAP Header条目
SOAP header条目包含可选的env:actor属性(参阅section 4.2.2)用来把他们定位到合适的SOAP结点。没有该属性的SOAP Header隐含地定位到一个匿名的SOAP actor,这意味着他们被处理为最终的SOAP接收者。我们把SOAP actor属性的值(隐含的或者直接指明的)作为相应SOAP条目(SOAP Header条目或者SOAP Body条目)的SOAP actor。


如果SOAP条目中SOAP actor(如果出现的话)匹配了一个SOAP结点的角色,或者是SOAP条目没有actor属性(包括SOAP Body条目)而该SOAP结点已经假设为匿名SOAP处理角色,这时我们就说SOAP条目被指向一个SOAP结点。


2.4 理解SOAP Header
我们认为随着时间的过去,会有大量的SOAP Header函数规范出现,而且每个SOAP结点都可以包含一个或多个处理这些扩展所必须的软件。如果SOAP结点的软件是完全兼容的而且实现了那些由条目中完整修饰的最外层元素名所传递的语义,我们说这个SOAP Header被一个SOAP结点理解。


当定位到一个SOAP结点的SOAP Header块的mustUnderstand属性为“1”,被指向的SOAP结点必须:或者依照由条目中完整修饰的最外层元素名传递的语义来处理SOAP块,或者更本不处理SOAP消息而失败(参见section 4.4).。


2.5 处理消息
本节陈述了SOAP消息处理规则。除非另外规定,处理必须在语义上等同于分别执行下述的步骤,同时还必须按照给定的顺序。注意到,无论如何在这个规范中都没有阻止使用如并行、回滚或者其他可以在处理中提高灵活性的技术,只要所有的SOAP消息、SOAP fault和应用程序级的结果和那些直接执行下列规则得到的结果是相同的。




如果一个或多个定位到SOAP结点的SOAP条目有env:mustUnderstand="1"并且没有被结点理解,则产生一个SOAP mustUnderstand错误。如果这样一个错误产生了,那么必须停止进一步的处理。



处理定位到SOAP结点的SOAP条目,如果需要,产生SOAP错误。当定义env:mustUnderstand="1"时,一个SOAP结点必须处理SOAP块。如果没有定义,那么SOAP结点可以处理或忽略该SOAP条目。如果一个SOAP条目被处理,无论如何,这个SOAP结点必须理解该SOAP条目而且必须以和那个SOAP条目说明完全一致的样式进行处理。而对于错误,无论是那种,也必须和SOAP条目的说明一致。有可能处理特殊SOAP条目会控制或者决定其他SOAP条目的处理顺序。例如,一个SOAP条目可能建立一个SOAP Header条目用来强制按词汇的顺序执行其他的SOAP Header条目。如果没有这样一个SOAP条目,处理的顺序是由SOAP结点来判断的。当处理一个SOAP条目的时候,SOAP结点可以引用SOAP envelope中的任何信息。例如如果需要,一个缓存函数可以缓存整个SOAP消息。


如果SOAP结点是一个SOAP中介,SOAP消息的式样和处理的结果(如果没有产生错误)可以要求进一步沿着SOAP消息路径送递SOAP消息。这种接力转递必须以同样顺序包括从SOAP消息源来的所有的SOAP Header条目和SOAP Body条目,除了那些指向SOAP中介的SOAP Header条目,这些条目必须被移去(无论他们是否被处理,这些SOAP条目都将被移去)。附加的SOAP Header条目可以被插入在SOAP消息的任何一点,这样被插入的SOAP Herder条目可能没法和刚刚被移走的一个或多个条目区分开来(实际上是会将他们保留,但强调需要沿着SOAP消息路径重新解释每个SOAP结点)


3. 与XML的关系
所有的SOAP消息都是使用XML格式来编码的(可参阅[7]以获得更多的XML的信息)。


SOAP应用程序在生成由SOAP定义的所有元素和属性的时候,应该包含恰当的SOAP命名空间。SOAP应用程序必须能处理其收到的消息中的SOAP命名空间。它必须丢弃那些包含不正确命名空间(参阅 section 4.4)的消息,并且可以处理那些不包含SOAP命名空间的SOAP消息,就好象他们包含了正确的命名空间一样。


SOAP定义了以下的命名空间 (可参阅[8]以获得更多的XML命名空间的信息):




SOAP信封的命名空间标识为 "http://www.w3.org/2001/06/soap-envelope"



SOAP遍序的命名空间标识为 "http://www.w3.org/2001/06/soap-encoding"



SOAP mustUnderstand fault的命名空间标识为 "http://www.w3.org/2001/06/soap-faults"



SOAP upgrade的命名空间标识为 "http://www.w3.org/2001/06/soap-upgrade"


而这些命名空间的模式文档可以通过解析这些命名空间标识符来获得。


SOAP消息必须不包含DTD,同时SOAP消息也必须不包含PI(Processing Instructions)。 [7]


SOAP使用局部的非限制的ID类型的id属性来指定编码元素(encoded element)的唯一标识,使用局部的非限制的uri-reference类型的href属性来指定编码元素的值的应用,以获得与XML规范[7]、XML Schema规范[11]和XML Linking Language规范[9]的一致。


除SOAP mustUnderstand属性(参阅 section 4.2.3)和SOAP actor属性(参阅 section 4.2.2)外,一般允许属性及属性值自由地选择是在XML实例中描述还是在XML Schema中描述,当然前提是他们具有相同的效果。也就是说,在DTD或模式(schema)中使用默认值或固定值定义在语义上等价于在实例中的定义。


4. SOAP信封
SOAP消息是由一个强制的SOAP Envelope、一个可选的SOAP Header和一个强制的SOAP Body组成的XML文档。作为SOAP消息的该XML文档将在本规范的其余部分被引用。而本节的元素和属性的命名空间标识是"http://www.w3.org/2001/06/soap-envelope"。SOAP消息应当包含如下部分:




一个SOAP envelope。Envelope是表示该消息的XML文档的顶级元素。



一个SOAP Header。Header则是为了支持在松散环境下在通讯方(可能是SOAP发送者、SOAP接受者或者是一个或多个SOAP的传输中介)之间尚未预先达成一致的情况下为SOAP消息增加特性的通用机制。SOAP定义了很少的一些属性来用于指明谁可以处理该特性以及它是可选的还是强制的。(参阅 section 4.2)



一个SOAP Body。Body为该消息的最终接收者所想要得到的那些强制信息提供了一个容器(参阅 section 4.3)。此外,SOAP定义了Body的一个子元素Fault用于报告错误。


语法规则如下:




SOAP Envelope




元素名为"Envelope"。



该元素必须在SOAP消息中出现。



该元素可以包含命名空间申明和额外的属性。如果出现额外属性,则必须有命名空间修饰。类似的,该元素可以包含额外的子元素,这些子元素如果出现,必须有命名空间修饰并且必须跟在SOAP Body元素之后。



SOAP Header (参阅 section 4.2)




元素名为"Header"。



该元素可以在SOAP消息中出现。如果出现,该元素必须是SOAP Envelope元素的第一个直接子元素。



该元素可以包含一系列的Header条目,这些条目都应当是Header元素的直接子元素。Header的所有直接子元素必须有命名空间修饰。



SOAP Body (参阅 section 4.3)




元素名为"Body"。



该元素必须在SOAP消息中出现,同时必须是SOAP Envelope元素的一个直接子元素。若该消息中包含Header元素,则Body元素必须直接跟随Header,为Header元素的相邻兄弟元素。若Header不出现,则其必须是Envelope的第一个直接子元素。



该元素可以包含一系列的Body条目,这些条目都应当是Body元素的直接子元素。Body的所有直接子元素必须有命名空间修饰。SOAP定义了SOAP Fault元素,它用来指示错误消息。(参阅 section 4.4).


4.1.1 SOAP encodingStyle属性
SOAP的全局encodingStyle属性被用于指明在SOAP消息中使用哪种编序规则。该属性可以在任意元素中出现,并且其作用范围包括该元素的内容和所有其子元素中未使用该属性的所有子元素,这就象XML命名空间定义的作用范围。对于一个SOAP消息来说,没有默认的编码定义。


该属性的值是一个或多个用于标识编序规则和用于标识解序SOAP消息的规则的有序列表,其排序是按照详尽程度从大到小排列。Example 3展示了encodingStyle属性的三个例子:



Example 3
encodingStyle="http://www.w3.org/2001/06/soap-encoding"
encodingStyle="http://example.org/encoding/restricted http://example.org/encoding/"
encodingStyle=""
Example values for the encodingStyle attribute
在section 5中定义的编序规则的标识为"http://www.w3.org/2001/06/soap-encoding"。消息若要使用特别的编序应该使用SOAP encodingStyle属性来指明。另外,所有在句法上由"http://www.w3.org/2001/06/soap-encoding"开始的URI序列表明这其中包含的所有URI都与section 5中定义的SOAP编码规则相一致。(虽然可能会添加潜在的更为严格的规则)


一个空值的URI(“”)明确地指明并未为其所包含的元素声明任何编码风格。这可以为包含的元素关闭任何声明。


4.1.2 Envelope版本模型
SOAP并未定义一个传统的基于主辅版本号的版本模型。SOAP消息必须包含一个与命名空间"http://www.w3.org/2001/06/soap-envelope"相关联的Envelope元素。如果SOAP应用程序收到一个SOAP消息,这个消息中的Envelope元素与一个与"http://www.w3.org/2001/06/soap-envelope"不同的命名空间相关联,则该应用程序必须视其为一个版本错误并生成一个VersionMismatch SOAP错误。SOAP VersionMismatch错误消息必须使用SOAP 1.1的信封命名空间"http://schemas.xmlsoap.org/soap/envelope/"(参阅 Appendix C)修饰。


4.2 SOAP Header
SOAP提供了一个可伸缩的机制用于在分散的模块化的环境下扩展SOAP消息,而通讯双方并不需要有预先的约定知识。典型的扩展例子可以是实现一些诸如认证、事务管理以及支付的Header条目。


SOAP Header元素应当被编码为SOAP Envelope XML文档的第一直接子元素。Header的所有直接子元素都被称为Header条目。


Header条目的编码规则包括:




一个SOAP Header条目由一个完整修饰的元素名来标识,所谓完整修饰的元素名是由一个命名空间URI和局部名来组成。SOAP Header元素的所有直接子元素都必须是完整修饰的。



SOAP encodingStyle属性可以用于指明Header条目的编码风格(参阅 section 4.1.1)。



SOAP actor属性(参阅 section 4.2.2)和SOAP mustUnderstand属性(参阅 section 4.2.3)可以用于指明由哪个SOAP结点来处理条目以及如何处理条目。


4.2.1 使用Header属性
本节中定义的SOAP Header属性决定了SOAP消息的接收者应该如何处理消息(参阅 section 2)。一个生成SOAP消息的SOAP应用程序应该仅使用SOAP Header元素的直接子元素的SOAP Header属性。而对于那些并非作为SOAP Header元素的直接子元素出现的SOAP Header属性,SOAP消息的接受者必须忽略。


以下是一个SOAP Header的例子(Example 4),其中包含了一个元素标识Transaction和一个mustUnderstand属性及其值1,以及Transactin的值5:



Example 4

  
    5
  


Example header with a single header block
4.2.2 SOAP actor属性
EdNote: This section partially overlaps with section 2. We expect this to be reconciled in a future revision of the specification.


SOAP消息从生成者到达最终接受者,将潜在地沿着消息路径(message path)经过一系列的SOAP中间介。SOAP中间介是一个能够接受和转发SOAP消息的应用程序。所有的中间介都如同最终接受者一样由一个URI来标识。


并非一个SOAP消息的所有部分都是最终接收者想要的,其中部分是路径中的一个或多个中间介所需要的。Header元素中接收者角色类似和约的接受者,他并不能将其交给其它方。也就是说,一个接收者接到其想要的一个Header元素必须不转发该Header给SOAP消息路径中的下一个应用程序,因为合约关系是存在于前二者之间的。该接收者可以插入一个类似的Header元素,但在这个情况下,和约关系存在于该应用程序及下一个Header元素的接收者之间了。


SOAP actor全局属性可以被用于指明Header元素的接收者。而SOAP actor属性的值是一个URI。这个特别的URI"http://www.w3.org/2001/06/soap-envelope/actor/next"指明该Header元素是直接的下一个进行消息处理的SOAP应用程序想要的。这与HTTP的连接头字段的hop-by-hop scope model的表示。


若省略SOAP actor属性,则表明接收者是SOAP消息的最终接收者。


这个属性必须出现在SOAP消息的实例中,而不能定义在相关的XML Schema中以期获得同样效果(参阅 section 3 和section 4.2.1)。


4.2.3 SOAP mustUnderstand属性
EdNote: This section partially overlaps with section 2. We expect this to be reconciled in a future revision of the specification.


SOAP mustUnderstand全局属性用于指明一个Header条目是强制的还是可选的要求接收者处理。Header条目的接收结点由SOAP actor属性来定义(参阅 section 4.2.2)。mustUnderstand属性的值可为“0”或“1”。若没有使用SOAP mustUnderstand属性,则在语义上等价于mustUderstand属性出现同时取值为“0”,也就是说这个条目是可选的。


若Header条目带有值为“1”的SOAP mustUnderstand属性,则该Header条目的接收结点要么必须遵循语义(由具备完整修饰的元素名来传达)并正确地处理这些语义,要么必须宣称处理消息失败(参阅 section 4.4)。


SOAP mustUnderstand属性是为了考虑健壮地升级而设置的。所有用值为“1”的SOAP mustUnderstand属性来标记的元素必须被认为是可以影响该元素的上级元素或同级元素的语义。而这种风格标记的元素应保证对语义的修改并不能被那些不能完全理解该修改后的语义的那些元素静默地或假设地、不正确地忽略。


该属性若要生效必须在实例中出现,而不能定义在相关的XML Schema中以期获得同样效果(参阅 section 3 和section 4.2.1)。


4.3 SOAP Body
SOAP Body元素提供一个简单的用于与消息的最终接收者交换强制信息的机制。而Body元素的典型应用包含序列的RPC调用和错误报告。


Body元素在编码上应当作为SOAP Envelope元素的一个直接子元素。如果包含Header元素,则Body元素必须直接跟随Header元素,为Header元素的直接下一个兄弟元素,否则Body元素必须是Envelope元素的第一直接子元素。


所有Body元素的直接子元素被成为SOAP Body条目,同时每一个Body条目都应当编码为SOAP Body元素里的一个独立元素。


Body条目的编码规则包括:




一个Body条目由一个完整修饰的元素名来标识,所谓完整修饰的元素名是由一个命名空间URI和局部名来组成。SOAP Body元素的直接子元素可以是命名空间修饰的。



SOAP encodingStyle属性可以被用来表明Body条目中使用的编码规则(参阅 section 4.1.1)。


SOAP定义了一个Body条目,用于报告错误的Fault条目(参阅 section 4.4)。


4.3.1 SOAP Header和Body的关系
Header和Body在定义上是独立的,但在事实上是相联系的。一个Body条目和一个Header条目的关系是:一个Body条目在语义上与这样一个Header条目等价,该Header条目将由默认参与者(最终接受者)解释同时由值为“1”的SOAP mustUnderstand属性标记。默认参与者可以使用actor属性缺失的方式来指明(参阅 section 4.2.2)。


4.4 SOAP错误
SOAP Fault元素是用于在SOAP消息中传输错误或状态信息。如果SOAP消息需要包含SOAP Fault元素的话,它必须作为一个Body条目出现,同时在Body元素内它必须不出现多于一次(至多出现一次)。


SOAP Fault元素定义了如下子元素:



faultcode

faultcode元素是应那些要提供一个算法上的机制来标识错误的软件的需要。faultcode必须在SOAP Fault元素中出现,同时faultcode的值必须是如[8]中的第3节中定义的一个修饰(限制)名。SOAP定义了一个很小的SOAP错误代码的集合用于覆盖基本的SOAP错误(参阅 section 4.4.1)。


faultstring

faultstring元素是为那些错误代码提供一个人可以读懂的错误解释,它不是为程序处理而设。Faultstring元素有点类似于HTTP中定义的’Reason-Phrase’(参阅 [5], section 6.1)。faultstring必须在SOAP Fault元素中出现,同时它至少应该提供一些解释该错误种类的信息。


faultactor

faultactor元素是为在SOAP消息路径(参阅 section 2)中是谁引起了该错误的发生这一情况描述信息。它类似于SOAP actor属性(参阅 section 4.2.2),不过它不是用于指示Header条目的接收者,而是用于指示错误源。faultactor属性的值是一个标识该源的一个URI。所谓并非作为SOAP消息最终接收者的应用程序必须在SOAP Fault元素中包含faultactor元素。而消息的最终接收者可以使用faultactor元素来明确地指明是它生成了该错误(参阅下面的detail元素]。


detail

detail元素是用于传输与SOAP Body元素相关的应用程序特别的错误信息。如果Body元素中的内容不能被成功地处理的时候,它必须出现。它必须不能被用于传输属于Header条目的错误信息。详细的属于Header条目的错误信息必须在Header条目中表示传输,如果需要例子的话,请参阅section 4.4.2。


若SOAP Fault元素中不出现detail元素则表明其中的错误与Body元素的处理无关。这可以用于区分在错误情况下Body元素是否被SOAP的最终接受者处理过。


detail元素的所有直接子元素都被称为detail条目,同时每个detail条目都作为detail元素中的一个独立的元素进行编码。


Detail条目的编码规则如下(也可以参阅 example 10):




一个detail条目由一个完整修饰的元素名来标识,所谓完整修饰的元素名是由一个命名空间URI和局部名来组成。Detail元素的直接子元素可以是命名空间修饰的。



SOAP encodingStyle属性可以被用来表明detail条目中使用的编码规则(参阅 section 4.1.1)。


4.4.1 SOAP错误代码
当描述由本规范定义的错误的时候,faultcode元素必须使用在本节中定义的faultode的值。这些faultcode值的命名空间标识为"http://www.w3.org/2001/06/soap-envelope"。在现有规范之外定义的方法的规范推荐使用该命名空间(但不是必须的)。


默认的SOAP faultcode值是按照一种可扩展的风格来定义的,它允许在维持已有的faultcode值的向后兼容的基础定义新的SOAP faultcode值。这一机制在使用上非常类似与HTTP中基本状态类的定义1xx, 2xx, 3xx等(参阅[5]中的section 10)。不过,他们是用XML修饰名来定义(参阅[8]中的section 3),而不是用整数。“.”符号是faultcode值的分隔符,用于指明“.”左边的是一个比右边更泛化的错误代码。Example 5显示了这一特性:



Example 5
Client.Authentication
Example of an authentication fault code
在SOAP中定义的faultcode值集合被罗列在下表。





Name
Meaning

VersionMismatch
处理程序发现在SOAP Envelope元素中有一个非法的命名空间。(参阅 section 4.1.2)

MustUnderstand
SOAP Header元素的一个直接子元素无法被理解或者他并不遵守由处理对象要求的SOAP mustUnderstand属性必须取值为“1”的要求。(参阅 section 4.2.3)

Client

Client错误类用于指示以下错误:消息的格式有误或消息中缺乏能成功处理所必须的一些适当信息。例如,消息中可能缺乏适当的认证和支付信息。一般情况下应指明消息不应该在没有修改过的情况下重发。可参阅section 4.4来参阅Fault detail子元素的描述。



Server

Server错误类用于表明消息无法被处理的原因,但那些属于内容上的错误并不属于该范畴,它主要被用于指示那些属于处理上的错误。例如,处理操作需要包含与一个上游处理程序进行通讯,但该程序没有响应。但该消息可能在下一个时间点上被成功处理。可参阅section 4.4来参阅Fault detail子元素的描述。


4.4.2 MustUnderstand错误
当SOAP结点产生一个MustUnderstand错误时,它应该在产生出的出错消息中按照下面描述的的方式提供相应的Header条目。在产生的错误消息中,它应该提供Header条目来描述不能被理解的带修辞的名的细节(Qnames,由XML Schema数据类型说明)。


每个这样的Header条目有个本地的名字为Misunderstood以及一个叫"http://www.w3.org/2001/06/soap-faults"的命名空间。每个块都有一个名为qname的不带修饰的属性,它的值为出错结点所不能理解的Header条目的Qname。


举例来说,如果最初消息的容器不能理解Example 6中的两个Header元素abc:Extension1和def:Extension2,则会产生出错消息,该消息显示在Example 7中。



Example 6

  
                           env:mustUnderstand=‘1‘ />
                           env:mustUnderstand=‘1‘ />
  

  
  . . .
  


SOAP envelope that will cause a SOAP MustUnderstand fault if Extension1 or Extension2 are not understood
 



Example 7
                      xmlns:f=‘http://www.w3.org/2001/06/soap-faults‘ >
  
                                    xmlns:abc=‘http://example.org/2001/06/ext‘ />
                                    xmlns:def=‘http://example.com/stuff‘ />
  

  
   
      MustUnderstand
      One or more mandatory headers not understood
   

  


SOAP fault generated as a result of not understanding Extension1 and Extension2 in Example 6
注意到这里不需要命名空间前缀返回与源Header元素命名空间相匹配的qname,倘若前缀映射到一个相同的命名空间名,则错误结点可使用任意前缀。


还注意到这里没有保证每个Mustunderstand错误都包含所有的Misunderstood Header 的Qname,SOAP结点可以在第一个Header块产生一个只包含单个Header块错误细节信息之后再产生一个错误。SOAP结点也可以产生一个一次包含所有MustUnderstand问题细节的混合错误。


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调用和响应的映射联合使用。


为了描述编码,以下术语将被使用:




“value”值是一个字符串(string)、一个可量度对象(数字、日期、玫举)的名字、或是数个简单值的组合。所有的值都有明确的类型。



“simple value”简单值是是一个不可分的值,它不包含任意可以命名的部分。简单值的离子可以是特定的字符串、证书或玫举值等。



“compound value”复合值是一个值的关系的聚集。复合值的例子可以是特定的采购定单、存货报表、街道地址等。



在一个复合值中,每一个相关的值都可以用一个角色名来区分,也可以用一个序数来区分,当然也可以同时使用两者。这被称为“accessor”存取标识。复合值的离子包括特定的采购定单、存货报表等。数组也是复合值。它可以被看成是具有多个相同名字的存取标识(accessor)的复合值,例如RDF。



“array”数组是一个复合值,在其成员值之间仅有顺序位置不同。



“struct”结构是一个复合值,在其成员值之间的区分是依靠存取标识(accessor)。同时所有存取标识的名应不同。



“simple type”简单类型是简单值的类。简单类型的例子包括那些类“string”, “integer”,玫举类等。



“compound type”复合类型是复合值的类。复合类型的例子包括采购定单的抽象类型,这些由该类型派生的采购定单具备相同的存取标识(shipTo, totalCost等),当然他们有不同的值(也许对某些值还有约束)。



在一个复合类型中,一个存取标识在本符合类型中是唯一的,如果它和其他复合类型中的某个存取标识无法相区别,则该存取标识名加上复合类型的名字才能成为唯一标识,这个名称为"局部名"。无论该名是直接或间接基于一个URI,如果该存取标识不用加类型名约束就已经是唯一的,那该名就成为"全局名"。



值表的编序的模式中所给出的信息,是有可能能决定一些值只能关联一个存取标识的简单实例。对于其他可能的情况,则无法下这个断言。一个值被称为”single-reference”单引用,如果只有一个存取标识能够引用它。如果能被多个引用,无论是事实上还是潜在可能,那就是”multi-reference”多引用。注意有可能在一模式中有一个确定的值是单引用而其他则是多引用。



在句法上,一个元素可以是"独立的"或"嵌入的"。一个独立的元素是作为编序中一个顶级元素出现。而其他则是嵌入元素。


尽管使用xsi:type属性可以令值的表示为自描述的,也就是说即包含值的结构也包含值的类型,但编序规则允许值的类型可以仅仅引用模式(Schema)中的类型定义。而这些模式可以使用“XML Schema Part 1: Structures”[10]和“XML Schema Part 2: Datatypes”[11]中定义的规范来描述,当然也可以使用其他的模式定义来定义。注意尽管这样,但许多模式定义只支持结构(struct)和数组(array)类型,而编序规则则有可能要尝试使用结构(struct)和数组(array)类型之外的复合类型。


编序规则如下:




所有的值都应当表现为元素的内容(content)。一个多引用的值必须被表示为一个独立元素的内容。而一个单引用的值应该不如此(不过也可以如此)。



对每个包含一个值的元素,值的类型表示必须满足以下至少一个条件:(a) 包含该值的元素实例包含一个xsi:type属性,(b) 包含该值的元素实例包含在一个具备enc: arrayType属性的元素中(可能是被设置成default的),(c) 该元素的名带有一个类型的明确关联,而该类型由一个模式来决定。



一个简单值应被表示为字符数据(character data),也就是说,没有任何子元素。每一个简单值必须有一个类型,该类型要么是在XML Schema规范的DataTypes部分[11]中被罗列,要么它的源类型应当在该部分中被罗列(可参阅 section 5.2)。



一个复合值应当被编码为一个元素序列,其中每一个存取标识由一个嵌入元素来表示,他们的名是一一对应的。若存取标识的名在包含它的型中是局部的,则它有一个未修饰的元素名,而其他则应有完全修饰的名(可参阅 section 5.4)。



一个多引用的简单或复合值应当被编码为一个独立元素,该独立元素应包含一个局部的带有非限制名的“id”属性,该属性的类型为XML规范[7]中定义的ID类型。对该值的每一个存取标识是一个空元素,该空元素有一个局部的未修饰的属性“href”,该属性类型是XML Schema规范[11]中定义的“uri-reference”类型,“href”属性的值是一个引用该对应独立元素的URI片段标识。



字串和字节数组被表示为多引用简单类型,不过特别的规则也允许它们在通常情况下更有效地表示(可参阅 section 5.2.1以及section 5.2.3)。一个字串或字节数组的存取标识可以有一个在XML规范[7]中定义的名为”id”的ID类型的属性。如果这样的话,所有其他对该同一值的存取标识可以被编码为一个空元素,该空元素应包含一个局部的带有非限制名的“href”属性,该属性的类型为XML Schema规范[11]中定义的“uri-reference”类型,“href”属性的值是一个引用该对应独立元素的URI片段标识。



对一个值编码多个引用是允许的,看上去这些引用好象是引用了多个不同的值,但仅当从上下文中可得到该XML 实例的含义是未改变的的结论。



数组是复合值(可参阅 section 5.4.2)。SOAP数组被定义为类型是“enc:Array”或类型是源于“enc:Array”。


SOAP数组有一或多维,而它的成员由顺序位置区分。一个数组的值被表示为一序列反映该数组的元素,这些成员按序数从小到大顺序出现。对于多维数组,则元素维按从右到左顺序变化。没一个成员元素都被命名为一个独立元素(参阅 rule 2)。


SOAP数组可以是单引用值,也可以是多引用值,从而可以被表示为一个嵌入元素或一个独立元素。


SOAP数组必须包含一个“enc:arrayType”属性,其中定义的包含元素的值的类型与维数一起描述了该数组。”enc:arrayType”属性的值定义如下:





arrayTypeValue
=
atype asize

atype
=
QName *( rank )

rank
=
"[" *( "," ) "]"

asize
=
"[" #length "]"

length
=
1*DIGIT
“atype”结构是数组所包含的元素的类型的名,首先它包含一个QName表示,QName应在XML Schema元素声明中的“type”属性中出现,QName是一个型约束(意味着所有其包含的元素都应宣称与该指明的类型相一致,也就是说,在enc:arrayType中引用的类型必须是所有数组元素的类型或超类型)。对于那些数组的数组或是“jagged arrays”,使用rank结构来表示数组的元素是一个数组,同时该数组的具体类型将在下层具体成员数组的定义时数值实例化,rank中出现零个、一个到多个逗号,表明该成员变量是一维、二维或多维数组。对于多维数组,维数定义为一个由“,”分隔的维数序列,每个维数的记数基数为1。


“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”属性的值定义为:





arrayPoint
=
"[" #length "]"
他们的基数都是0。



NULL值和默认值可以在存取标识元素中省略。NULL值可以在一个存取标识元素中使用一个值为1的属性xsi:null来指明,或者可以是其他依赖于应用程序的属性和值。


注意rule 2允许独立元素和数组中成员元素对于包含的类型可以有不同的名。


5.2 简单类型
对于简单类型,SOAP采用了在“XML Schema Part 2: Datatypes”[11]的“Build-in datatypes”节中定义的所有类型,包括值和词汇空间(lexical spaces)。例子包括:





Type
Example

int
58502

float
314159265358979E+1

negativeInteger
-32768

string
Louis "Satchmo" Armstrong
在XML Schema规范中声明的数据类型可以直接在元素模式中使用。而源于这些类型的类型也可以被使用。下面是一个模式片段和相应类型元素数据的例子:



Example 7
















Schema with simple types
以下是一些合法的元素实例:



Example 8

45
5.9
-450
Blue
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
45

5.2.1 字符串
“string”数据类型在“XML Schema Part 2: Datatypes”[11]中被定义。值得注意的是在许多数据库或编程语言中,“string”类型并不是一致的,在某些特别的语言中,可能只允许一些字符能出现在“string”中。(这些值可能需要表示为xsd:string之外的一些数据类型)


一个字串可以被编码为一个单引用或多引用值。


包含string值的元素可以有一个“id”属性。额外的存取标识元素可以有匹配它的“href”属性。


例如,如果有两个对同一string的存取标识出现,则可以表现为:



Example 10
Hello

Two accessors for the same string
无论如何,事实上对一个string(或者是string的子类型)的实例加以两个引用与将他们编码成两个单引用值并没有本质的区别:



Example 11
Hello
Hello
Two accessors for the same string
对于这些例子的模式描述可能是:



Example 12
xmlns:enc="http://www.w3.org/2001/06/soap-encoding" >







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
xmlns:tns="http://example.org/2001/06/samples"
targetNamespace="http://example.org/2001/06/samples" >











Schema with enumeration




Example 14
Brown
Message fragment corresponding to the schema in Example 13
5.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
xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
xsi:type="enc:base64" >
aG93IG5vDyBicm73biBjb3cNCg==

Image with base64 encoding
5.3 多态存取标识
许多语言允许存取标识可以多态地访问数个类型的值,在运行时刻每个类型都是可使用的。一个多态存取标识实例必须包含一个“xsi:type”属性以描述类型的实际值。


例如,一个名为“cost”带有类型为“xsd:float”的值的多态存取标识可以编码为:



Example 16
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xsi:type="xs:float">29.95

Polymorphic accessor
与之相对的是一个值类型不变的cost存取标识。



Example 17
29.95
Accessor whose value type is invariant
5.4 复合类型
SOAP依照在程序语言中常常看见的以下结构模式来定义复合类型:



Struct

“struct”是一个复合类型值,其成员的存取标识名是相互区别的唯一标志,应彼此各不相同。


Array

“array”是一个复合类型值,其成员的顺序位置是相互区别的唯一标志。


SOAP也允许数据的编序即不是Struct也不是Array,例如在Directed-Labeled-Graph数据模型中单个数据结点有很多不同的存取标识,其中有些会出现多次。SOAP遍序并不需要下层的数据模型要区别存取标识的次序区别,但如果有这种次序存在的话,那么存取标识必须按照该次序编码。


5.4.1 复合值及对值的引用
复合值的成员被编码为存取标识元素。存取标识由他们的名字来相区别(例如在struct里面),而元素名就是存取标识名。存取标识名是局部的,作用域是包含他们的类型中,具备一个未修饰的元素名,而其他则有完全修饰名。


下面是一个“Book”结构的例子:



Example 18

Henry Ford
Prefactory text
This is a book.

Book structure
下面则是一个描述该结构的模式片段:



Example 19
xmlns:xs=‘http://www.w3.org/2001/XMLSchema‘ >








Schema for Example 18
下面是一个即包含简单类型成员也包含复合类型成员的类型的例子。它显示了两层的引用。注意“Author”存取标识元素的“href”属性一个对匹配“id”值对应的值的引用。“Address”中的情况也是类似的。



Example 20

My Life and Work


id="Person-1" >
Henry Ford



id="Address-2" >
mailto:henryford@hotmail.com
http://www.henryford.com

Book with muli-reference addresses
当“Person”和“Address”的值是需要多引用的时候,上述描述是合适的。如果使用单引用来描述,则应该是嵌入的,如下:



Example 21

My Life and Work

Henry Ford

mailto:henryford@hotmail.com
http://www.henryford.com



Book with single-reference addresses
如果这里存在着一个限制:在一个给出的实例中不允许有两个人有同样的地址,地址可以是一个街道地址(Street-address),也可以是一个电子地址(Electronic-address)。一本有两个作者的书可以编码为:



Example 22

My Life and Work



xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
id="Person-1" >
Henry Ford

mailto:henryford@hotmail.com
http://www.henryford.com


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
id="Person-2">
Samuel Crowther

Martin Luther King Rd
Raleigh
North Carolina


Book with two authors having different addresses
编序也可以包含一些不在同一资源中的值的引用:



Example 23

Paradise Lost


Book with external references
同时下面是一个对上面结构的模式描述片段:



Example 24
xmlns:tns="http://example.org/2001/06/books"
targetNamespace="http://example.org/2001/06/books" >






Either the following group must occur or else the
href attribute must appear, but not both.


















Either the following group must occur or else the
href attribute must appear, but not both.

















Either one of the following sequences must occur or
else the href attribute must appear, but not both.























Either the second sequence in the following group
must occur or else the href attribute must appear,
but not both.



























Either the first sequence in the following group
must occur or else the href attribute must appear,
but not both.
























Schema for example 22
5.4.2 数组
SOAP数组被定义为类型为“enc:Array”或类型源于“enc:Array”(可参阅 rule 8)。这种类型源于"enc:Array"的类型必须遵从"enc:Array"的限制,同时它可用于表示以下情况的类型定义,譬如整型数的数组或是一些用户自定义的枚举类型的数组等。数组被表示为对包含其的元素的名无特殊约束的元素值(就象值一般不会约束包含元素的名)。组成数组的元素可以是任意类型,包括嵌套的数组。


数组值的表示是一个该数组组成元素的一个有序序列。作为一个数组的值,元素名对于区分存取标识并非重要。元素可以有任意的名。实际上,这些元素的命名将按照模式中声明的建议,或由他们的类型所决定。就象在复合类型中通常情况下,如果数组中条目的值是单引用值,则该条目将包含它的值。否则,条目通过“href”属性引用它的值。


下面是一个模式的片段以及一个包含integer成员的数组:



Example 25
xmlns:enc="http://www.w3.org/2001/06/soap-encoding" >



Schema declaring an array of integers




Example 26
xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
enc:arrayType="xs:int[2]" >
3
4

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
xmlns:xs="http://www.w3.org/2001/XMLSchema"
enc:ArrayType="xs:int[2]" >
3
4

Using the enc:Array element
数组可以包含任意指定arrayType的子类型的实例。也就是说,成员的类型可以是任何描述在arrayType属性中类型的可替代类型,这将依照于在模式中表示的可替代规则。因此,例如,一个整数数组可以包含任何源于integer的类型的值(例如 “int”或任何用户定义的源于integer的类型)。类似的,一个“address”数组可以包含一个严格的或扩展的类型,比如“internationalAddress”。因为提供的enc:Array类型允许包含任何类型或类型混合的成员,除非有对arrayType属性使用的特别限制。


成员元素类型在实例中可以使用xsi:type来描述,或则是在成员元素模式中声明,就象在下面两个数组中分别演示的那样:



Example 28
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
enc:arrayType="xs:anyType[4]">
12345
6.789

Of Mans First Disobedience, and the Fruit
Of that Forbidden Tree, whose mortal tast
Brought Death into the World, and all our woe,


http://www.dartmouth.edu/~milton/reading_room/


Array with elements of varying types




Example 29
xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
enc:arrayType="xs:anyType[4]" >
12345
6.789

Of Mans First Disobedience, and the Fruit
Of that Forbidden Tree, whose mortal tast
Brought Death into the World, and all our woe,


http://www.dartmouth.edu/~milton/reading_room/


Array with elements of varying types
数组值可以是结构或其他复合值。例如一个“xyz:Order”结构的数组:



Example 30
xmlns:xyz="http://example.org/2001/06/Orders"
enc:arrayType="xyz:Order[2]">

Apple
1.56


Peach
1.48


Arrays containing structs and other compound values
数组也可以有一些成员值是数组。下面是一个有两个数组的数组的例子,而那两个数组都是string数组:



Example 31
xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
enc:arrayType="xs:string[][2]" >



xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
id="array-1"
enc:arrayType="xs:string[2]">
r1c1
r1c2
r1c3

xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
id="array-2"
enc:arrayType="xs:string[2]">
r2c1
r2c2

Array containing other arrays
包含一个数组值的元素并不需要一定被命名为“enc:Array”。它可以有任意的名,而提供的类型则要么是enc:Array,要么是受源于enc:Array的限制。例如,下面是一个模式片段以及与之一致的一个实例数组:



Example 32
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" >




















Schema for an array




Example 33
xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
enc:arrayType="abc:phoneNumberType[2]" >
206-555-1212
1-888-123-4567

Array conforming to the schema in Example 32
数组可以是多维的。在这种情况下,就会有多个描述维数大小的值出现在arrayType属性的asize部分:



Example 34
xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
enc:arrayType="xs:string[2,3]" >
r1c1
r1c2
r1c3
r2c1
r2c2
r2c3

Multi-dimensonal array
上述例子中显示了一个数组如何被编码为独立元素,数组值可以以嵌套方式出现并且如果他们是单引用的话,应该使用这种方式。


下面是一个模式片段的例子以及符合该模式的一个嵌套在“Person”结构中的电话号码数组,该数组可以从存取标识“phone-numbers”访问:



Example 34
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" >
































Schema fragment for array of phone numbers embedded in a struct




Example 35
xmlns:enc="http://www.w3.org/2001/06/soap-encoding" >
John Hancock

206-555-1212
1-888-123-4567


Array of phone numbers embedded in a struct conforming to the schema in Example 34
下面是单引用数组值的另一个例子,数组值被编码为嵌入元素,这些元素都包含作为存取标识的元素名:



Example 36

Henry Ford

5th Ave
New York
NY
10010

enc:arrayType="xyz:Order[2]">

Apple
1.56


Peach
1.48



Single-reference array encoded as en embedded element
5.4.2.1 部分传输数组
SOAP提供对部分传递数组的支持,这就象在一些上下文[12]中的“可变长”数组。一个部分传递数组应使用“enc:offset”属性标识,该属性的记数是以第一元素的位移为0开始的。如果省略该属性,则位移默认是0。


下面是一个大小为5的数组,同时在传递的时候仅传递第三和第四个元素:



Example 37
xmlns:xs="http://www.w3.org/2001/XMLSchema"
enc:arrayType="xs:string[6]"
enc:offset="[3]" >
The fourth element
The fifth element

Array of size five that transmits only the third and fourth element
5.4.2.2 稀疏数组
SOAP提供对稀疏数组的支持。每一个表示成员值的元素包含一个“enc:position”属性来表明它处于数组的位置。下面是一个二维字串数组的稀疏数组的例子。他的大小是4,但仅有位置2被使用:



Example 38
xmlns:xs="http://www.w3.org/2001/XMLSchema"
enc:arrayType="xs:string[,][4]" >


enc:arrayType="xs:string[10,10]" >
Third row, third col
Eighth row, third col

Sparse array
如果在上述数组中对array-1仅有一个引用,那上述例子可以被编码为:



Example 39
xmlns:xs="http://www.w3.org/2001/XMLSchema"
enc:arrayType="xs:string[,][4]" >

Third row, third col
Eighth row, third col


Another sparse array
5.4.3 通用复合类型
上面引用到的编码规则并不限于那些预先知道存取标识的情形。如果存取标识名仅当在编码过程中由值的出现才能决定的时候,同样的规则也可以应用,也就是一个存取标识被编码为同名的元素,并且该存取标识要么包含要么引用它的值。包含那些类型不能预先决定的值的存取标识必须包含一个合适的xsi:type属性来给出值的类型。


类似的,引用的规则对于包含一些混合的存取标识的复合类型的编序而言已经足够了,这些存取标识有的是以名来区分,有的是以名和位置来区分 (也就是说,有些存取标识会重复出现) 。这并不一定需要有包含这一类型的模式存在,但是如果一个类型模型模式没有该类型时,那么一个对应的XML句法模式和实例就应该被生成。



Example 40

Henry Ford

5th Ave
New York
NY
10010



Apple
1.56


Peach
1.48



Generic compound types
类似的,将一个复合类型值编序为类似数组结构的是合法的,但这不是enc:Array类型或其子类型。例如:



Example 41


Apple
1.56


Peach
1.48


Compound value
5.5 默认值
一个省略格式的存取标识元素以为着有一个默认值或是尚不知道它的值。而该细节是基于存取标识、方法和上下文的。例如一个省略格式的存取标识典型地是表示一个多态存取标识的Null值(Null依赖存取标识的确切含义)。同样地,一个省略格式的Boolean存取标识典型地就意味着是一个False值或值未知,同时一个省略格式的数值存取标识典型地意味着它的值是0或值未知。


5.6 SOAP root属性
SOAP root属性可以被用来标注编序的根,当然他并不是对象图真正的根,所以对象图是可以解序的。该属性可以赋予“0”和“1”这两个值的任意一个。一个对象图的真正的根一般就有值“1”。那些非真正根的编序根也可以被标注为赋予值为“1”的编序根。一个元素也可以被明确地标注为赋予值为“0”的非编序根。


SOAP根属性可以出现在SOAP Header和SOAP Body元素中的任何子元素里,该属性并没有一个默认值。