用XSLT进行WSDL处理

日期: 2008-05-20 作者:Uche Ogbuji 来源:TechTarget中国

  在先前几篇介绍 Web 服务描述语言 (WSDL) 和基于 WSDL的 RDF 应用的基础上,本文演示一些以不同方式使用可扩展样式表变换语言(XSLT) 处理 WSDL 的方法。需要熟悉 XSLT 和资源描述框架(RDF)。本文提供了介绍 XSLT 的参考资料。


  IBM、Microsoft 和 Ariba 于 9 月份完成的 Web 服务描述语言 (WDSL) 的模式开发实际上只是增强 Web 服务体系结构尝试的开始。130 家公司的通用描述、发现和集成 (UDDI) 的倡议,包括 WSDL 之后的团队,是更基础的部分。随着情况的进展,已经有人在说:这些规范将如何开始产生实际的实现 — 从 IBM 范围广阔的 AlphaWorks 工具到 Microsoft.NET 策略。来自 Web 服务中公司 stakeholder 的这批工具将首先出现在更大的框架中,并且通常是紧密地构建在那些框架中。


  但是,在使格式适应当前应用之前无需等待集成的 WSDL 工具。只需万维网联盟的通用工具集 扩展样式表变换语言 (XSLT),WSDL 就可以做很多事。XSLT 无疑是 W3C 最成功的杰作之一。它有 30 多个独立且嵌入产品中的实现。阅读本文时,您应该熟悉 XSLT 和资源描述框架 (RDF)。


  IT 仅用这个新的 XML 时髦词语来试图使 Web 更有魔力,就深受从有经验的程序员到疲倦的 Web 管理员等用户的喜爱。但最重要的是,它一直是用于测试大量 XML 结果的先驱工具。在规范上的墨迹未干之前,Eric van der Vlist 就使用 XSLT 将 XML 部分插入不知不觉的语法分析器。Rick Jeliffe 的由 XSLT 支持的 Schematron 提供了一种确认很多使用名称空间的 XML 词汇的方法,而 XML 模式仍然发展得缓慢。事实上,极其无耻的是,甚至有 XML 模式的 Schematron 确认器。在这种情绪下,我们将在本文中使用 XSLT 作为探测器来看一下实际的 WSDL。


  探寻 WSDL 中的数据


  Web 服务白页和黄页的开发人员以及服务供应商本身,都会对在各种报告和目录格式中显示 WSDL 描述的数据感兴趣。XSLT 是用于这种数据抽取和报告的极佳工具。


  在第一篇 WSDL 文章(请参阅 参考资料 )中,我们给出了一个描述查询认可特定产品的职业滑雪者的服务描述示例。该服务中的请求和响应用简单对象访问协议 (SOAP) 传输。 清单 1 是显示在描述中指定的可用服务简洁表的 XSLT 变换。这些服务的传送和位置也被抽取出来。


  即使对于这样一个简单用途,变换相当复杂。部分复杂性在于 WSDL 1.0 处理内容的方式。例如,关系是使用来自 XML 名称空间的限定名称表单的属性指定的。然而,XSLT 1.0 不提供处理 XML 名称空间范围之外的名称空间扩展的工具。这实际上已经在 XSLT 界作为对 XSLT 1.1 受欢迎的附加部分而讨论过了,因为很多规范(WSDL、XML 模式和 XSLT 本身)都在内容中使用限定名称。这些设施将使清单 1 简单得多。


  清单 1 ,模板 1.1 简单地设置了 HTML 样板文件。接下来,是一些使用键的查询表。不是所有的键都在清单中实际使用,但是我在清单中显示表 1.1 到 1.4,以演示基本模式。键收集代表顶级 WSDL 组件的元素节点,按其名称元素检索。


  查询表 1.5 更为有趣。在后面的变换中,我们将列出在每一个端口的绑定期间指定的传送。WSDL 在具有本地名 “binding” 的元素中指定这一点。查询表 1.5 在每个 WSDL 绑定元素中捕获该元素。


  模板 1.2 输出每个 WSDL 服务元素的表。它们中大多数都是普通的 XSLT。它使用 “pull” 模型(显式循环并用 XPath 取值)而不是 “push” 模型(模板匹配)来以直接的方式剪切感兴趣的数据。中央循环为服务元素中的每个端口输出一行。在标号之后,从具有本地名称 “address” 的元素显示 location 属性。请注意,只检查本地名称,因为 WSDL 指定两种 “address” 元素类型:一种用于 SOAP,另一种用于 HTTP;另外,还允许我们的变换所支持的某些扩展。


  接下来是使用 binding-uri 变量和依次使用 binding-local-name 的传送。这两个变量都在 xsl:for-each 中定义。在 binding-local-name 定义中,可以看到我所说的属性中的限定名是什么意思。要使端口绑定属性的内容与相应的 WSDL 绑定元素匹配,必须除去名称空间前缀,这由 substring-after() 函数完成。


  binding-uri 变量使用 binding-local-name 作为到查询表 1.5 的索引,如果您记起的话,该表将每个绑定的名称映射成其特定于传送的绑定元素的名称空间 URL。在我们的示例中, binding-uri 最终将是 SOAP URI: http://schemas.xmlsoap.org/wsdl/soap/ 。回到第三个表单元中, binding-uri 被用作到查询表 6 的索引,该表将名称空间 URI 转换成如 “SOAP” 这样的描述字符串。


  查询表 1.6 值得仔细研究,因为它使用了高级 XSLT 技术。它使用独特的名称空间在样式表中构建起查询表。您可以在键的下面看到 x:ns-to-binding 元素。如果熟悉键,则您知道它们定义索引,而这些索引将在与 match 属性中的模式匹配的原始源文档中的节点上被构建。还不为人所知的是:每次用 XSLT document() 函数装入附加源文档时,还对它应用所有的键。变换结束标记之前的 xsl:variable 使用特殊的 document() 调用形式来将样式表作为附加源文档装入。这样,就索引了样式表中与 ns-to-binding 匹配的节点。对于无需删改源文档或无需依赖附加文件而设置查询表来说,这时一个非常有用的技术。您将在本文的后面再次看到对它的使用法。


  在 Unix 命令行使用 4XSLT 应用程序(请参阅 参考资料)运行变换,如下所示:


  [uogbuji@borgia wsdlxslt]$ 4xslt
  http://uche.ogbuji.net/articles/wsdl/endorsementservice.xml
  http://uche.ogbuji.net/articles/wsdl/wsdlservicesummary.xslt
 
  如您所能看到的,我已经使原始 WSDL 源文件和清单 1 样式表可以联机获得。有关详细信息,请参阅“参考资料”一节。图 1 显示了该变换的输出结果。



  图 1. 应用清单 1 中的样式表之后得到的浏览器视图
 
  应该很容易理解如何扩展该变换以从 WSDL 源抽取如消息部分等附加信息。下一节,我们将讨论更复杂且侧重点不同的 XSLT 变换用法。


  从 WSDL 生成 RDF


  在过去有关 WSDL 的文章中,我们讨论了 WSDL 可能的 RDF 形式。与 RDF 一样,WSDL 的全部内容都与描述有关,因此,我们指出 RDF 可能是 WSDL 的理想形式。幸运的是,既然 RDF 非常灵活,就有可能提出与 WSDL 原始格式差别不大的 RDF 兼容格式。现在,我们将看一看如何使变换自动化。


  可以使用 清单 2 中的变换来将我们的 WSDL 样本从第一篇文章转换成在第二篇文章中作为示例给出的 RDF 版本。


  首先要指出的是: 清单 1 中的变换更多地是使用 “pull” 模型(基于 xsl:for-each 指令)来显示服务中的不同端口,而本样式表几乎全部基于 “push” 技术。具有仔细选择匹配和适当方式的模板设置了执行路径。大多数 XSLT 新手更习惯于 pull 技术,因为对于熟悉过程模型(例如 ECMAScript 的过程模型)的人来说,它们显得更为自然。因此,以上变换可能需要多一点时间来理解,但是对于进行从一种 XML 格式转换成另一种的非结构调整来说,它是很好的通用模型。


  模板 2.1 开始进行处理。 xsl:copy 用来复制 wsdl:description 元素。第一个 xsl:apply-templates 复制其属性。


  第二个 xsl:apply-templates 试图复制子元素,但是请留意,它不指定模式。如果看一下该清单的余下部分,您就会看到对于 WSDL wsdl:types ,这将由模板 2.7 匹配,该模板只递归地继续复制那个元素下的所有子树。而一旦到达 wsdl:description 的下一子节点,情况就会改变。 wsdl:message 匹配模板 2.4,该模板是为空过程。到目前为止的效果是:抑制除 wsdl:types 之外的所有 WSDL 元素子代。


  第三个 xsl:apply-templates 作同样的事,但却指定 convert-to-rdf 方式。然后,处理器再次遇到 wsdl:types ,但是这次与作为空过程的另一个模板 2.6 匹配。然而,所有其它顶级 WSDL 元素由模板 2.2 处理 — 它开始进行到 RDF 格式的转换。当然,按要求将这部分输出封装在 rdf:RDF 元素中。


  变换的其余部分主要是这些机制的继续。还记得上一篇文章中所讲的吗:通过添加从初始 name 获得的 rdf:ID 属性来在顶级子代中转换成 RDF。在模板 2.2 中通过显示 xsl:attribute 来做到这一点。另外请注意,必须为顶级 WSDL 元素的每个属性添加显示名称空间。这由以 convert-to-rdf 方式匹配属性的模板 2.5 处理。请注意,它使用我们设置的查询表,并且该表采用将样式表作为源文档装入的技术。查询表将名称空间 URI 映射成在输出中使用的前缀。


  如模板 2.3 和 2.4 中,处理顶级 WSDL 元素子节点的方法略有不同。这些不同的方法是为了适应我们在 RDF 表示中所选择的简化,例如将 wsdl:message/wsdl:part 元素作为匿名资源以及将 @message 属性转换成 rdf:resource 属性。


  再次使用 4XSLT,对初始 WSDL 源文档所作的该变换的输出与上一篇文章中的 RDF 版本类似。即使对 RDF 格式的 WSDL 不感兴趣,上面的样式表也是多种 WSDL 调整的开始框架。


  结束语


  本质上,WSDL 非常简单:只是联机服务的描述。然而,因为 UUDI 以前所作的工作和打下的基础,它注定要在多种应用中被使用。 Rich Site Summary (RSS) 系统就是简单格式如何拥有广泛用途的示例。本文所介绍的技术演示了几种用 XSLT 变换处理 WSDL 的方法。


  清单 1 对简单的联机报告和编目(特别是当您需要对变换进行简单调整时)很有用。在这种情况下,输出与输入在结构上很少有类似之处,并且只选取用于输出的材料较为合理。清单 2 中的 pull 方法对于在与 WSDL 相同的结构基础中操作的变换是很有用的。例如,您可能要查看除去后缀名的 WSDL 文件,或者可能在 API 摘要的所有级别上抽取 WSDL 文档元素。对于将 WSDL 关系重设为 XLinks 来说,它可能也有用。这样的链接可能是内部的,当使用 WSDL 导入器来分解描述时,它们也可能是外部链接。更进一步,作为扩展设施,可以将链接处理成链接到 WSDL 导入设施之外的外部资源。这样的变换看起来与清单 2 不会有太大不同。


  希望本系列文章给出了 WSDL 的有用介绍并提供了一些工具来开始处理使用当前可用 XML 技术的格式。随着 WSDL、UDDI 和其它这种技术的成熟和聚合,将有一个不断改进的应用和服务供应商核心利用这样的应用。某一天,这可能会使平滑集成 Web 服务的梦想向现实更靠近一步。


  关于作者


  Uche Ogbuji 是 Fourthought Inc. 的顾问和共同创始人,这是一家专为企业知识管理应用提供 XML 解决方案的咨询公司。Fourthought 开发了 4Suite ,这个 XML 中间件的开放源平台。Ogbuji 先生是计算机工程师和作家,他出生在尼日利亚,在美国科罗拉多州居住和工作。可以通过 uche@fourthought.com 与他联系。 

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐