IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  XML  >

技巧: 使用 XInclude 同步带有源大纲的 WSDL

为 document/literal 消息描述导入有效负载格式

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 中级

Uche Ogbuji (uche.ogbuji@fourthought.com), 首席顾问, Fourthought, Inc.

2004 年 2 月 01 日

在 document/literal 方式的 Web 服务中,交换格式的模式通常基于现有的文档标准。这可能造成带有标准大纲的 WSDL 文件的同步问题。这篇技巧说明了如何利用 XInclude 将外部模式片段结合到 WSDL 文件中。

WSDL 文件中的 types 部分提供的 XML 模式代码片段,用于对 Web 服务中进行交换的 XML 格式化。在绝大多数情况下,这就是 SOAP 主体的内容。在 RPC 方式的 Web 服务中,一般使用专门的 XML 格式将 W3C XML Schema (WXS) 结构映射为 SOAP 编码。这种格式完全针对具体的 Web 服务,在它以外没有什么真正的用途。这样就划分了可能在通信两端应用程序层使用的 XML 和最终通过导线实际传输的格式,这种区分常常是 RPC 方式 Web 服务被批判的要害,同时也是鼓吹 document/literal 方式的基础。如果您不熟悉 document/literal 方式,请参阅 参考资料中的介绍。

在 document/literal 方式中,对两端的处理而言意义最明确的 XML 格式直接捆绑到信封中,原样传输。这意味着,进入 WSDL types 部分的模式细节,通常只是一种更通用的模式的一部分。甚至可能是全球共知的模式,如 XHTML、Docbook 或者用于商业交换的许多 XML 格式(UBL、OGSIS 等)之一。这意味着把模式嵌入 WSDL 文档可能引起同步或者一致性问题。如果整个模式改变了,但没有能够及时弥补所有需要相应修改的 WSDL,会怎么样呢?可能引起的问题微不足道,但也可能导致大的灾难。

引入包含

W3C XInclude 规定了一种处理模型和语法,把对外部文档的引用展开成该文档中实际的 XML(或者其中的一部分)。这个过程称为包含,其他语言中也有类似的机制,比方说 C 或 C++ 中的 #include 。从技术上讲, XML 包含是通过把一些 XML 信息集合并成单个复合 Infoset 完成的。只要模式文件存放在某个地方,就可以将其包含到 WDSL 文件中。作为一个例子,比方说您要在常量 Web 服务中发送清单 1 中所示的文档。


清单 1. 在常量 Web 服务中发送的示例文档
<?xml version="1.0" encoding="iso-8859-1"?>
<labels>
  <label>
    <quote>
      Midwinter Spring is its own season
    </quote>
    <name>Thomas Eliot</name>
    <address>
      <street>3 Prufrock Lane</street>
      <city>Stamford</city>
      <state>CT</state>
    </address>
  </label>
  <label>
    <name>Ezra Pound</name>
    <address>
      <street>45 Usura Place</street>
      <city>Hailey</city>
      <state>ID</state>
    </address>
  </label>
</labels>
      

这种格式在清单 2 所示的 W3C XML Schema 中格式化。


清单 2. 要传送的常量文档的 W3C XML Schema
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="qualified"
>
  <xs:element name="labels">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="label"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="label">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" ref="quote"/>
        <xs:element ref="name"/>
        <xs:element ref="address"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="quote">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:element ref="emph"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="emph" type="xs:string"/>
  <xs:element name="name" type="xs:string"/>
  <xs:element name="address">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="street"/>
        <xs:element ref="city"/>
        <xs:element ref="state"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="street" type="xs:string"/>
  <xs:element name="city" type="xs:string"/>
  <xs:element name="state" type="xs:string"/>
</xs:schema>
      

清单 3 是 WSDL 文件的 types 类型部分,包括了模式定义的必需部分。


清单 3. 使用 XInclude 来合并 XML 模式的 WSDL 部分
  <types xmlns:xi="http://www.w3.org/2001/XInclude">
    <schema>
      <xi:include
        href="http://example.com/labels.xsd"
        xpointer="xmlns(xs=http://www.w3.org/2001/XMLSchema)
                  xpointer(/xs:schema/*)"
      />
    </schema>
  </types>
      





回页首


取我所需

清单 3 中的例子并不是直接包含整个文件。对于这个 WSDL 我只需要模式文件中的元素定义,因此使用 XPointer 从整个模式中提取这个子集。XPointer 为这类提取定义了几种方案。 xmlns(...) 方案定义了名称空间映射, xpointer(...) 方案规定了定义所用文档子集的表达式。它是基于 XPath 的,表达式 /xs:schema/* 和它在 XPath 中的含义是一样的,即仅仅选择 xs:schema 元素的孩子。

警告:这种 XPointer 语法是正确的,也是现行的注明日期为 2003 年 11 月 10 日的工作草案所采用的语法,但是和以前在 XInclude 中表示 XPointer 的方式不同。经过测试,我发现那种工具还没有升级到新的约定,所以您可能暂时必须使用旧的等价形式,如清单 4 中所示。


清单 4. 清单 3 的一种变体——使用旧式的 XPointer 约定
  <types xmlns:xi="http://www.w3.org/2001/XInclude">
    <schema>
      <xi:include
        href="http://example.com/labels.xsd#
                  xmlns(xs=http://www.w3.org/2001/XMLSchema)
                  xpointer(/xs:schema/*)"
      />
    </schema>
  </types>
      

注意:"xmlns(" 开始的部分通常紧跟在井号的后面,而不是单独占一行,为了格式更清晰我分了行。





回页首


结束语

XInclude 是简单的并被许多 XML 工具所支持。在许多情况下它是一种便利的工具,并确实有助于提高 document/literal 样式的 WSDL 文档的可维护性。



参考资料



关于作者

Uche Ogbuji 的照片

Uche Ogbuji 是 Fourthought Inc.的顾问和共同创始人,该公司是专为企业知识管理提供 XML 解决方案的软件供应商和咨询公司。Fourthought 开发了 4Suite,这是一个用于 XML、RDF 和知识管理应用程序的开放源代码平台。Ogbuji 先生是一位出生于尼日利亚的计算机工程师和作家,他现在美国科罗拉多州博耳德(Boulder)生活和工作。可以通过 uche.ogbuji@fourthought.com与 Ogbuji 先生联系。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款