本文考察了一些顶尖的 XML 模式,这些模式为各种各样的问题提供了解决方案,从基本的 Web 服务到数据描述等等。其中包括涉及到通讯录和发票的类似数据库的解决方案。本文选择模式的标准是根据其实用性和用途,及其在 XML 信息共享和交换方面对 XML 社区的影响。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
简单对象访问协议(Simple Object Access Protocol,SOAP)实际上是一种 Web 服务技术,但 Web 服务中客户机和服务器之间的数据交换格式是通过灵活的 XML 模式实现的。
Web 服务的主要优点是客户机和服务器通过网络进行信息和数据交换的互操作性的层次。SOAP 标准使用 XML 以一种体系结构中立的格式来构造数据,定义数据类型和信息。
对于编程语言来说,只需要提供数据类型和需要在远程服务器上调用的函数名称即可。SOAP 库将用主机语言编写的信息和格式转化成 XML 格式的消息,其中包括调用的函数和提供的参数。
通过 W3C 的例子就可以了解 SOAP 的结构。调用远程 SOAP 函数 GetEndorsingBoarder() 的时候,客户机上的调用程序生成清单 1 所示的 XML 消息。
清单 1. 调用远程 SOAP 函数 GetEndorsingBoarder()
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <m:GetEndorsingBoarder xmlns:m="http://namespaces.snowboard-info.com"> <manufacturer><?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><place w:st="on">K2</place></manufacturer> <model>Fatbob</model> </m:GetEndorsingBoarder> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |
SOAP 客户机发送的整个消息都放在 SOAP 信封中。信封的内容就是消息的详细内容。
被调用的函数显然是 GetEndorsingBoarder,它包括两个参数:manufacturer 和 model。由此可见,它把本地的可能采用二进制编码的字符串转化成了 XML 字符串。由于 XML 是平台独立的,主机使用 SOAP 系统不需要复杂的二进制编码和解码就可以交换消息。
服务器通过另一个 XML 编码的 SOAP 信封返回响应,这一次是函数的返回值。SOAP 请求的响应格式与函数相同,只不过在信封内容的后面加上了 Response,如清单 2 所示。
清单 2. SOAP 请求的响应
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <m:GetEndorsingBoarderResponse xmlns:m="http://namespaces.snowboard-info.com"> <endorsingBoarder>Chris Englesmann</endorsingBoarder> </m:GetEndorsingBoarderResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |
通常不需要自己编写 SOAP 消息,SOAP 库会自动生成。不过 SOAP 信封的结构和简单性表明使用 SOAP 标准共享信息很简单。
SOAP 大大简化了交换消息和调用远程函数的工作。远程过程调用(Remote Procedure Call,RPC)标准需要复杂的方法来处理二进制数据的序列化,发送结构化更高的信息需要详细的声明和双向的信息转换。
使用 SOAP,XML 序列化大大降低了这种复杂性,使得跨平台、跨语言集成和数据交换更加简单。
Web 服务描述语言(Web Services Description Language,WSDL)提供了一种描述 Web 服务(大多使用 SOAP)的简单方法。WSDL 允许您描述利用 SOAP 标准所提供的服务和接口。
比方说,可以创建描述某台服务器上提供的服务的 WSDL 文件,然后把该文件分发给需要这些服务的 Web 服务消费者。通过阅读和解析 WSDL 文件,消费者能够了解到使用这些 Web 服务需要知道的所有信息,包括可以交换的数据类型、参数以及返回的各种错误和其他信息。
再次使用来自 W3C 的例子,可以看到不同远程函数的声明和交换的数据都是通过结构的 XML 定义处理的,如清单 3 所示。
清单 3. 不同远程函数和交换数据的 XML 定义
<?xml version="1.0"?>
<!-- root element wsdl:definitions defines set of related services --> <wsdl:definitions name="EndorsementSearch" targetNamespace="http://namespaces.snowboard-info.com" xmlns:es="http://www.snowboard-info.com/EndorsementSearch.wsdl" xmlns:esxsd="http://schemas.snowboard-info.com/EndorsementSearch.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<!-- wsdl:types encapsulates schema definitions of communication types; here using xsd --> <wsdl:types>
<!-- all type declarations are in a chunk of xsd --> <xsd:schema targetNamespace="http://namespaces.snowboard-info.com" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<!-- xsd definition: GetEndorsingBoarder [manufacturer string, model string] --> <xsd:element name="GetEndorsingBoarder"> <xsd:complexType> <xsd:sequence> <xsd:element name="manufacturer" type="string"/> <xsd:element name="model" type="string"/> </xsd:sequence> </xsd:complexType> </xsd:element>
<!-- xsd definition: GetEndorsingBoarderResponse [... endorsingBoarder string ...] --> <xsd:element name="GetEndorsingBoarderResponse"> <xsd:complexType> <xsd:all> <xsd:element name="endorsingBoarder" type="string"/> </xsd:all> </xsd:complexType> </xsd:element>
<!-- xsd definition: GetEndorsingBoarderFault [... errorMessage string ...] --> <xsd:element name="GetEndorsingBoarderFault"> <xsd:complexType> <xsd:all> <xsd:element name="errorMessage" type="string"/> </xsd:all> </xsd:complexType> </xsd:element>
</xsd:schema> </wsdl:types>
<!-- wsdl:message elements describe potential transactions -->
<!-- request GetEndorsingBoarderRequest is of type GetEndorsingBoarder --> <wsdl:message name="GetEndorsingBoarderRequest"> <wsdl:part name="body" element="esxsd:GetEndorsingBoarder"/> </wsdl:message>
<!-- response GetEndorsingBoarderResponse is of type GetEndorsingBoarderResponse --> <wsdl:message name="GetEndorsingBoarderResponse"> <wsdl:part name="body" element="esxsd:GetEndorsingBoarderResponse"/> </wsdl:message>
<!-- wsdl:portType describes messages in an operation --> <wsdl:portType name="GetEndorsingBoarderPortType">
<!-- the value of wsdl:operation eludes me --> <wsdl:operation name="GetEndorsingBoarder"> <wsdl:input message="es:GetEndorsingBoarderRequest"/> <wsdl:output message="es:GetEndorsingBoarderResponse"/> <wsdl:fault message="es:GetEndorsingBoarderFault"/> </wsdl:operation> </wsdl:portType>
<!-- wsdl:binding states a serialization protocol for this service --> <wsdl:binding name="EndorsementSearchSoapBinding" type="es:GetEndorsingBoarderPortType">
<!-- leverage off soap:binding document style ...(no wsdl:foo pointing at the soap binding) --> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<!-- semi-opaque container of network transport details classed by soap:binding above ... --> <wsdl:operation name="GetEndorsingBoarder">
<!-- again bind to SOAP? ... --> <soap:operation soapAction="http://www.snowboard-info.com/ EndorsementSearch"/>
<!-- further specify that the messages in the wsdl:operation "GetEndorsingBoarder" use SOAP? ... --> <wsdl:input> <soap:body use="literal" namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/> </wsdl:input> <wsdl:output> <soap:body use="literal" namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/> </wsdl:output> <wsdl:fault> <soap:body use="literal" namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/> </wsdl:fault> </wsdl:operation> </wsdl:binding>
<!-- wsdl:service names a new service "EndorsementSearchService" --> <wsdl:service name="EndorsementSearchService"> <wsdl:documentation>snowboarding-info.com Endorsement Service</ wsdl:documentation>
<!-- connect it to the binding "EndorsementSearchSoapBinding" above --> <wsdl:port name="GetEndorsingBoarderPort" binding="es:EndorsementSearchSoapBinding">
<!-- give the binding an network address --> <soap:address location="http://www.snowboard-info.com/EndorsementSearch"/> </wsdl:port> </wsdl:service>
</wsdl:definitions>
|
WSDL 声明了消息类型、默认数据类型和内容以及交换的数据结构。
访问服务器上 SOAP 结构需要使用的一切信息都可以在这个 WSDL 中找到。大多数语言和环境都提供一种阅读和解析 WSDL 的机制,以确定可用的函数和数据交换。
WSDL 不仅定义了用于交换信息的 SOAP 接口,通过适当的 WSDL 生成程序,还可用于创建发送请求、生成并格式化响应所需要的代码。
RDF
语义 Web(Semantic Web)和语义网格(Semantic Grid)技术都依赖于资源描述框架(Resource Description Framework,RDF)这种灵活的描述语言。RDF 格式实际上是一个标准家族的成员之一。它用于描述信息和资源,使得系统很容易连接和关联不同的资源。
RDF 是另一种经过 W<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="3" unitname="C">3C</chmetcnv>批准的标准,它用于定义信息和资源。RDF 不需要 XML,但一种用于描述信息的序列化格式采用了 XML。
定义资源需要指定一个包含主语、谓词和宾语的表达式。比方说,如果描述一个网站的内容,主语就是该网站,谓词是 “包含信息”,宾语就是内容的类型。建立该网站和其他资源的联系,可使用 Friend of a Friend (FOAF) 标记建立两个资源之间的链接。
RDF 的目的是将关于资源和信息的自然语言的陈述转化为机器可解析的格式。比如可将 The MCSLP.com Website is authored by Martin C Brown 这句话改写为清单 4 所示的 RDF XML。
清单 4. RDF XML 格式的陈述
<rdf:RDF xmlns:rdf="http://www.w3.org/<chsdate w:st="on" isrocdate="False" islunardate="False" day="22" month="2" year="1999">1999/02/22</chsdate>-rdf-syntax-ns#" xmlns:si="http://www.recshop.fake/siteinfo#"> <rdf:Description rdf:about="http://www.mcslp.com/ "> <si:author>Martin C Brown</si:author> </rdf:Description> </rdf:RDF> |
采用 RDF 标准的另一个例子是新闻站点和博客早期提供的连锁系统,它们使用 RDF 规范定义提要内容和不同的新闻。清单 5 提供了一个例子。
清单 5. 利用 RDF 规范定义提要内容和不同的新闻
<?xml version="1.0"?> <rdf:RDF xmlns:rdf="http://www.w3.org/<chsdate w:st="on" isrocdate="False" islunardate="False" day="22" month="2" year="1999">1999/02/22</chsdate>-rdf-syntax-ns#" xmlns="http://my.netscape.com/rdf/simple/0.9/">
<channel> <title>MCslp</title> <link>http://www.mcslp.com</link> <description>MCslp Projects</description> </channel>
<item> <title>Voice enabling XMLtitle> <link>http://mcslp.com/?p=295link> </item>
...
</rdf:RDF> |
RDF 标准最初设计的目的是描述 Web 上的资源、内容和关系。但是 RDF 现在变成了用于描述一般信息、资源和关系的标准。
语义 Web 和网格技术都需要定义资源及其之间的关系,使应用程序能够使用不同的信息,并且可以把数据捆绑在一起。
记录联系方式对所有商务应用程序都非常重要,通过有效的 XML 结构来捕获这些信息可以简化此类数据的处理。
联系信息变化可能很大,因此应该选择 XML 。比如,有些公司和个人可能有多个地址、电话号码和电子邮件帐户。在 XML 结构中很容易声明多个此类信息片段。
vCard 结构经常在 Internet 上用于表示联系信息,它独立于平台,很容易生成和导入不同的应用程序。它支持 XML 结构的某些灵活性,但实际上是一种基于文本的简单格式,使用声明性字段和扩展来提供信息。不同于 XML,vCard 格式是扁平文本,就是说不能直接向各种元素增加信息。电话号码是一个很好的例子,它不一定和某个地址关联,而仅仅作为记录中的另一个电话号码。
W3 联盟提出一种 vCard 格式的 XML,它采用 RDF XML 标准,以便于格式化和交换联系信息。采用 RDF 框架可以在声明过程中保留一些结构化信息。比如,RDF 标准支持使用包、序列和替代来描述数据。包支持多次声明一个对象(比如多种角色),并且可以在序列不重要时使用包。序列用于定义对象的次序,比如机构中人员角色的层次结构。替代允许从列表中选择一项,比如多个电子邮件地址。
清单 6 显示了虚拟人物 Charles Perston 的 vCard。
清单 6. Charles Perston 的 vCard
BEGIN:VCARD VERSION:3.0 N:Perston;Charles;;; FN:Charles Perston ORG:Perston Technology; EMAIL;type=INTERNET;type=WORK;type=pref:null@perston.co.uk TEL;type=WORK;type=pref:01234 567890 item1.ADR;type=WORK;type=pref:;;Perston House;Perston;Perstonshire;P1 0NS;<country-region w:st="on"><place w:st="on">UK</place></country-region> item1.X-ABADR:gb X-ABUID:5AE47BB6-4E<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0F</chmetcnv>-4558<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="True" hasspace="False" sourcevalue="980" unitname="C">-980C</chmetcnv>-BD3066FA6154\:ABPerson END:VCARD |
采用 vCard XML 标准,可用清单 7 中的结构表示同样的信息。
清单 7. 使用 vCard XML 标准表示 Charles Perston
<vCard:vCard xmlns:rdf="http://www.w3.org/<chsdate w:st="on" isrocdate="False" islunardate="False" day="22" month="2" year="1999">1999/02/22</chsdate>-rdf-syntax-ns#" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:foaf="http://xmlns.com/foaf/0.1/" vCard:version="3.0" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" vCard:class="PUBLIC" |