内容


借助 RDF 增强您的 WSDL

管理结构化的 Web 服务元数据

Comments

Web 服务描述语言 (WSDL)(请参阅“参考资源”)规范提供了一个基于XML 的简单语汇表,用来描述可通过网络提供的基于 XML 的 Web服务。这些服务本身使用简单对象访问协议 (SOAP)、HTTP、SMTP或通过其他方式进行通信;而 WSDL为用户提供设置这些通信所需的元数据。WSDL本身不规定如何发布或公布这种服务描述,而是将这项任务留给其他规范。“通用描述、发现和集成(UDDI)”是用来创建 Web 服务目录的一个倡议,它定义了对 WSDL描述进行编目和调度的一个框架,但是它刚刚出现而且相当复杂。

UDDI是对在线合同的一个巨大促进,理应很快在分布式服务领域占据一席之地。不过,因为最初的WSDL 部署很可能在严格封闭的系统中,而不是在开放的 Web上,所以可能会有一种更好的替代方案。有一种较早的更自然的方法用于以资源描述框架(RDF) 形式进行 WSDL 编目和发现。RDF 是由万维网联盟 (W3C)开发的一种机制,用来对 Web元数据进行编码和管理(请参阅“参考资源”)。它提供一些简单的方法来集成多个域中的大量元数据。

为了有助于理解本文,您可能需要阅读我的前一篇文章,"Using WSDLwith SOAPApplications"(请参阅“参考资源”),在那篇文章中我通过一个具体的示例分析了WSDL 规范的功能,那个示例说明测雪板专家为他们行业的厂商提供认可的一项服务。本文讨论借助RDF 的简单性和强大功能增强 WSDL 的描述能力。为了熟悉 RDF、RDFSchema 以及 RDF 的基本 XML表示(这对于理解本文后面的部分非常重要),请回顾“参考资源”部分有关RDF 信息的链接。

RDF 和 WSDL 本可能会是...


WSDL 提供的一切本来完全可以用 RDF 序列化格式编写。IBM、Microsoft 和Ariba 未考虑到这一点而作出了一个奇怪的选择。其他有点类似的标准,如RDF Site Summary (RSS),说明如何将 XML 资源描述格式表示为 RDF 的XML 序列化。 这并非对所有标准都有意义 -- 比如说,人们几乎不会期望Scalable Vector Graphics (SVG) 工作组 围绕 RDF 设计SVG。但是,当大多数信息表示简短标签和资源之间的关系时,RDF因其不断增加的用户和工具而变得很有意义。

例如,我已经使用上面讨论的一个 WSDL规范修改了测雪板示例,以便使用 RDF 序列化格式,如 清单 1所示。

清单 1:测雪板认可搜索的 WSDL描述在用有效的 RDF 语法表示时的形式。

<?xml version="1.0"?>
 <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:w="http://schemas.xmlsoap.org/wsdl/"
   xmlns="http://schemas.xmlsoap.org/wsdl/">
   <types>
     <schema targetNamespace="http://namespaces.snowboard-info.com"
             xmlns="http://www.w3.org/1999/XMLSchema">
       <element name="GetEndorsingBoarder">
         <complexType>
           <sequence>
             <element name="manufacturer" type="string"/>
             <element name="model" type="string"/>
           </sequence>
         </complexType>
       </element>
       <element name="GetEndorsingBoarderResponse">
         <complexType>
           <all>
             <element name="endorsingBoarder" type="string"/>
           </all>
         </complexType>
       </element>
       <element name="GetEndorsingBoarderFault">
         <complexType>
           <all>
             <element name="errorMessage" type="string"/>
           </all>
         </complexType>
       </element>
     </schema>
   </types>
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
     <message w:name="GetEndorsingBoarderRequest"
              rdf:ID="GetEndorsingBoarderRequest">
       <part w:name="body" w:element="esxsd:GetEndorsingBoarder"/>
     </message>
     <message name="GetEndorsingBoarderResponse"
              rdf:ID="GetEndorsingBoarderResponse">
       <part w:name="body" w:element="esxsd:GetEndorsingBoarderResponse"/>
     </message>
     <portType w:name="GetEndorsingBoarderPortType"
               rdf:ID="GetEndorsingBoarderPortType">
       <operation w:name="GetEndorsingBoarder">
         <input rdf:resource="GetEndorsingBoarderRequest"/>
         <output rdf:resource="GetEndorsingBoarderResponse"/>
         <fault rdf:resource="GetEndorsingBoarderFault"/>
       </operation>
     </portType>
     
     <binding w:name="EndorsementSearchSoapBinding"
              w:type="es:GetEndorsingBoarderPortType"
              rdf:ID="EndorsementSearchSoapBinding">
       <soap:binding soap:style="document"
                     soap:transport="http://schemas.xmlsoap.org/soap/http"/>
       <operation rdf:about="GetEndorsingBoarder">
         <soap:operation
           soap:soapAction="http://www.snowboard-info.com/EndorsementSearch"/>
         <input>
           <soap:body soap:use="literal"
             soap:namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/>
         </input>
         <output>
           <soap:body soap:use="literal"
             soap:namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/>
         </output>
         <fault>
           <soap:body soap:use="literal"
             soap:namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/>
         </fault>
       </operation>
     </binding>
     
     <service w:name="EndorsementSearchService"
              rdf:ID="EndorsementSearchService">
       <documentation>snowboarding-info.com Endorsement Service</documentation> 
       <port rdf:about="GetEndorsingBoarderPort">
         <binding rdf:resource="EndorsementSearchSoapBinding"/>
         <soap:address soap:location="http://www.snowboard-info.com/EndorsementSearch"/>
       </port>
     </service>
   </rdf:RDF>
 </definitions>

这些更改基本上是抽取描述的一部分并将其编码为 RDF 序列化。正如 RDF Model and Syntax 1.0 Recommendation(RDFM&S)(请参阅参考资源)所要求的那样, 这个部分包括在 rdf:RDF 元素中。如果将它输入 RDF处理器,您将获得大量信息,这些信息勾划出组成 WSDL说明的限制条件和关系。 我使用可用的每个 RDF 序列化技巧将对原始 XML结构的更改减到最少。 它很好地说明了 RDF 工作组必须对 RDF M&S进行多么艰苦的处理,才能使现有的 XML 格式归结 到有效的 RDF形式中。请注意,这一点也是引起极大争议的原因,因为有许多可用的技巧使得从各种语法和所生成的RDF 抽象模型的转换具有一定的脆弱性。

我未将 types 元素包括在 RDF部分。主要问题是这部分内容实际上完全超出了 WSDL 的范围。W3C 或其他Web 标准组织可能提出一个将 XML 方案映射到 RDF的标准,并且其他数据分类方法可能完成相同的工作,但它实际上属于完全不同的另一范畴的工作。 types 描述可能仍然可通过指定 parseType="Literal" 属性完全插入 RDF模型中,但我们同时必须面对随 parseType="Literal" 而来的所有问题: 尤其是,RDF M&S明确禁止包含标记的文字之间的等价定义(例如,它可能这样规定,如果带有标记的两段文字约简到正规XML 以后完全相同,则它们等价)。这意味着我们永远无法对以 RDF模型存储的数据与任何其他数据进行可靠的比较。在实际应用中,这使得 parseType="Literal" 毫无用处,所以我也就没管它。

转换为 RDF 的部分中,最显著的更改是在核心 WSDL元素中添加了 rdf:ID 属性。 这是 RDF 对 WSDL作者对属性中的限定名执行的操作的处理方式:建立抽象实体之间的关系。通过使用 rdf:resource 属性就可以看到在何处生成对这些已标识资源的引用。

您会注意到的另一个更改是,所有以前无前缀的属性现在都添加了一个前缀。RDF缩写允许将 namespace-resolved 属性当作特性名对待。属性值则成为语句的文字值。 在 清单 1中我大量使用了此缩写。RDF并不严格要求特性名的名称空间,但极力建议将它作为消除这些名称的歧义的方法。如果您准备将此 WSDL元数据放入包含其他信息的模型中,则常用的标签(如"name")很有可能与另一个特性表示(比如说,人名或组织名)发生冲突。因为 XML Namespaces 1.0不允许应用程序将缺省名称空间用作属性,所以我们必须明确地指定前缀来消除歧义。

在某些情况下(如消息部分),我使用匿名资源。请注意, message/part 元素有 property 属性,但没有 rdf:IDrdf:about 属性。我选择这样做是因为在我看来,很少需要引用消息上下文之外的消息部分,而且只有此操作才需要让它为非匿名。否则,我就不得不构造一个唯一的ID(不像顶级资源那样自然),并在 rdf:about 属性中使用XPointer,或某个其他技巧。我只是跟着最自然的感觉走。

最后几点注意事项。您可以看到,我在 service 元素中使用 rdf:about 添加了一条语句,这条语句涉及我以前作为其主题说明的那个端口。这是利用RDF 语法的灵活性将对原始 WSDL的更改减至最少的另一个示例。此外,您可以看到 RDF描述的任意嵌套是多么有用,它允许我们的 binding 元素版本保留它原始的结构。

WSDL 的详细图形表示,多亏RDF


最后,根据我们分析过的 WSDL 1.0 规范,我上面的示例并不是有效的WSDL。幸运的是,从正式语法生成 RDF 非常简单,既可以通过提供 WSDL文档中数据的同一来源中的自动化处理生成, 也可以使用 XSLT生成(我的下一篇关于 WSDL的文章将提供其实现方式的示例)。我在本文中提供的 RDF表示仍然有用,因为它提供了用 WSDL 编码的元数据的一个具体 RDF模型。我认为这离掌握全部相关和实用的语句已相当接近了。这样,使用从WSDL 中抽取的任何特定 RDF语法来构造相同的模型就是一件简单的事了。

WSDL 的 RDF 模型的一大优点是它直接导致 WSDL模型所指定内容的方便可视化。通过将元数据映射到RDF,我已将它套进一种形式化中,RDF M&S为此形式化提出了一种有用的表示作为定向图。如要看实际操作,请转到Dan Brickley 的卓越的 RDF 可视化工具(请参阅“参考资源”),并在URL 文本框中输入下面的 URL:
http://www-4.ibm.com/software/developerworks/library/ws-rdf/endorse.rdf。
我已将要查看的文档的一个副本列在 清单 1中。

请快速浏览一下生成的图形。如果使用可视化工具的 GIF输出,看它需要费点劲,所以如果您有诸如 Adobe SVGPlug-in(请参阅参考资源)之类的查看器,我建议使用 SVG输出。此外,您也可以从这个观测器站点生成 2 维虚拟现实标记语言(VRML)。请注意,已为匿名资源分配了一个生成的统一资源标识符(URI),这个标记符对于 RDF 工具很有用,尽管它与 RDF M&S中给出的图形样例有所不同,在 RDF M&S中匿名资源用空椭圆表示。例如,分配到的 URI 包含在第一个 message 元素中的匿名端口资源是:
http://www-4.ibm.com/software/developerworks/library/ws-rdf/endorse.rdf#genid3。
另请注意,显式绘制的 rdf:type 属性,在清单 1中是使用分类节点隐式绘制的,而没有使用 rdf:description 元素。

用于 WSDL 的 RDF Schema?


图中揭示的类型特性暗示了一种用于 WSDL 的 RDFSchema,该方案可用作转换为一种 RDF 模型的形式框架。WSDL规范仍然不提供任何 RDF Schema,但在 清单 2中我对其中的原因提出了最恰当的建议。它并不是 WSDL 的一个完整 RDFSchema;它只包含 清单 1中的示例的一个子集,而此子集又只使用了 WSDL的一个子集,但这可望成为进一步工作的基础。

应注意的第一点是,大小写与 RDF Schemas Candidate Recommendation(RDF Schemas) 中使用的约定不一致。这是为了避免改变 WSDL所用的元素类型名。除此之外,它还是循环的方案。只要 WSDL对描述元素之间的内部关系有相应的限制,我就使用 domain-range- 约束。因此,举例来说,因为 WSDL输入元素中的消息属性的值必须是消息名,所以 RDF Schema 使用 清单 3中代码段的等价范围约束。

清单 3. RDF Schema的范围约束

 <rdf:Property ID="input">
 <rdfs:range rdf:resource="message">
 <rdfs:domain rdf:resource="operation">
 </rdf:Property>

上面的范围约束确保输入特性只能在操作元素中使用,这也是 WSDL的一个约定。

但是,请注意,其中许多约束并不是它们所能达到的最强约束。例如,元素属性指明消息部分使用的类型部分中的特定元素。该特性的值实际上应该是一个有效的qname。例如,我们不能将字符串 " !!42xyz-- "设置为该特性的值,因为它甚至不是一个有效的 XML元素类型名,但是因为我们将 rdfs:Literal 用作该特性的范围,所以 RDF 处理器将会容忍这种错误。不幸的是,RDFSchema几乎没有提供对数据分类的支持,这个任务留给了以后的版本,那个版本将能够利用XML Schema 小组的工作。

出于策略方面的考虑,为了保持简单,我选择我的子集不包括 SOAP操作。为了使特定于 SOAP的语句处在它们自己的名称空间中,看来很可能必须有另一个 RDF Schema文件用于这些类和特性,而且必须借助发布这些方案的 WSDL作者的一些帮助。但是,再强调一次,RDF Schema的任何使用,包括我在本文中设置的框架,都需要拥有基准"http://schemas.xmlsoap.org/wsdl" URL(请参阅参考资源)的 WSDL作者的某些帮助。大多数 RDF 处理器,包括我在本文中使用的4RDF,可以帮助开发人员避开这个问题,它允许开发人员映射和覆盖基准URI。其他 RDF 处理器或许也可以完成这一工作。

掌握 XSLT...


正如本文所述,通过将 WSDL 映射到 RDF,就可将服务描述自动合并到识别RDF 的搜索引擎和分类系统中。W3C已经利用它的巨大影响力鼓励厂商和网站管理员使用 RDF对他们的内容进行分类,这将提高嵌入式服务描述的价值。如果是这样,那么"services Web"(盗用 XML 评论员 Len Bullard的一个术语)的白页和黄页就会变得像限制为 WSDL 方案的 RDF搜索一样简单。比 UDDI用户拼装的巨大框架简单得多,但这完全是另一个话题。

文本可望使您对如何借助可用于 RDF 的现有工具来体验 WSDL有所领悟。我们看过了用 WSDL 编码的元数据关系的内部结构,RDF转换使这一点更加清晰。我们也了解了从非 RDF 的 XML 语汇表导出 RDFSchema 和实例的一般过程。 在下一篇文章中,我们将会看到 W3C的另一项核心技术(即 XSLT)能为 WSDL 开发人员和用户做哪些工作。


相关主题

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文.
  • 我的前一篇文章, Using WSDL with SOAP Applications,说明了 WSDL 的工作方式以及它如何应用到基于 SOAP 的应用程序编程
  • 回顾 Web 服务描述语言(WSDL) 规范。
  • W3C 维护着一个 RDF 信息网页,您可以从该网页获得进一步的信息。
  • 要进一步提高您的 RDF 水平,请试一试这篇 教程
  • 我使用 Dan Brickley 的令人惊奇的 RDF visualizer生成了我们刚讨论过的 WSDL 描述的图像,格式为 GIF(141 KB) 和 SVG(27 KB)(要查看该文件请下载 Adobe SVG plug-in。安装插件程序后,在插件程序或 Web 浏览器中打开任一个 RDF 文件来以图形方式查看它)。RDF 源代码是本文中的 清单 1,我也提供了它的一个 副本
  • 您可能也对将 RDF 方案可视化工具用于 清单 2感兴趣。
  • W3C 的 SVG 网页上有许多 SVG 资源。
  • 我使用 4RDF 处理并测试本文的 RDF 文件和方案,图形生成除外。

评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=SOA and web services
ArticleID=52789
ArticleTitle=借助 RDF 增强您的 WSDL
publish-date=01012003