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

developerWorks 中国  >  XML  >

揭示 XProc

使用管道技术支持 XML 应用环境

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

英文原文

英文原文


级别: 中级

James R. Fuller (jim.fuller@webcomposite.com), 技术总监, FlameDigital Limited & Webcomposite s.r.o.

2008 年 7 月 21 日

从 2005 年 10 月起,W3C XML 处理模型工作组就开始研究名为 “XProc: An XML Pipeline Language” 的工作草案(Working Draft,WD)规范。随着早期的实现开始出现,以及 W3C 工作组对第二次 Last Call 的预报(为 W3C 草案建议铺平道路),很明显,在过去的一年里,对 Xproc 规范的研究工作已经加快了速度。探索 Xproc 的现状和未来,了解一些有争议的问题背后的故事,并演示一些例子。

Xproc 是一种描述处理管道的标记语言,由一些在 XML 文档上进行操作的离散步骤组成。如果规范的重要性与从事此项工作的个人素质有关,那么 Xproc 的确意义重大。W3C XML 处理模型 WG 聚集了大量务实的 XML 工作者和著名人物,还有过去对 XML 相关成果做出贡献的头发花白的老手:Erik Bruchez、Andrew Fang、Paul Grosso、Rui Lopes、Murray Maloney、Alex Milowski、Michael Sperberg-McQueen、Jeni Tennison、Henry Thompson、Richard Tobin、Alessandro Vernet、Norman Walsh(主席)和 Mohamed Zergaoui 等等。

常用缩写词
  • DTD:文档类型定义 (Document Type Definition)
  • HTTP:超文本传输协议 (Hypertext Transfer Protocol)
  • W3C:万维网联盟 (World Wide Web Consortium)
  • XML:可扩展标记语言 (Extensible Markup Language)
  • XSL:可扩展样式表语言 (Extensible Stylesheet Language)
  • XSLT:可扩展样式表语言转换 (Extensible Stylesheet Language Transformations)

Xproc 并不是 W3C 对建立一个 XML 处理管道标准所做的第一次尝试。在 2002 年,作为 XML Processing Model Workshop 的一部分,Sun Microsystems、Alis Technologies、Arbortext、Cisco Systems、Fujitsu、Markup Technology 和 Oracle 就曾提交了一个 “XML Pipeline Definition Language Submission”,并于 2002 年 2 月 28 日作为 “XML Pipeline Definition Language Version 1.0” 出版。

2004 年,W3C Note 曾尝试建立 XML 处理模型的需求:“XML Processing Model Requirements”,该需求由 W3C Working Group Note 于 2004 年 4 月 5 日完成。2005 年 3 月 11 日,Orbeon, Inc. 提交了另一个 W3C 成员报告 “XML Pipeline Language (XPL) Version 1.0”(草案),该报告于 4 月 11 日出版。

我还没见过针对 Xproc 需求的专门研究,因此,在这里我大胆提出自己的一些片面观点:

  • Xproc 的说明性格式以及管道思想的简单性,将意味着非技术人员能够参与处理工作流的编写和维护。
  • 在许多配置中,Xproc 都能够进行流线化,而其他控制 XML 处理的方法却无法实现这一点(例如 XSLT)。
  • Xproc 步骤专注于执行具体操作,随着时间的推移,这种方法将比您或我编写的一次性代码具有更好的优化性能。
  • Xproc 的标准步骤库和扩展机制使 Xproc 成为了一种全能的解决方案。
  • 结构化数据(例如 Xproc 标记)通常比结构化代码更易重用。
  • Xproc 的灵感之一来自 UNIX® 管道,几乎所有人都认为这是一个不错的功能!
用例

Xproc 的目标是提供一种可互操作的标准方法来处理 XML 文档。这些需求被正式列在一组用例中(参见 参考资料),下面列出了其中的部分内容:

  • 对 XML 文档执行一系列操作。
  • 解析 XML,针对一种模式对其进行验证,然后执行 XSLT 转换。
  • 合并多个 XML 文档(文档聚合)。
  • 与 Web 服务交互。
  • 使用元数据检索。

毫无疑问,Xproc 将会受到使用和生成 XML 文档的人群的喜爱。也可以想象经常处理业务工作流和 XML 文档的人群也会从中受益,他们可以使用 Xproc 管道对工作流进行建模,然后在 XML 文档中运行。

XProc 词汇表

Xproc 由一个小词汇表组成,该词汇表可以分为三个类别:核心元素,辅助元素和一个标准的步骤库。核心元素提供现代计算机语言构造,例如条件和循环处理以及尝试/捕获错误机制:

  • <p:for-each>循环处理语句
  • <p:choose>选择逻辑语句(类似于 XSLT <xsl:choose>
  • <p:group>将一系列步骤分组到指定的子管道中
  • <p:try>提供一种尝试/捕获机制来处理动态错误
  • <p:viewport>对包含在单个 XML 文档中的子树应用子管道进程

在步骤的声明和定义中使用的元素为 Xproc 的可扩展性和可重用性提供了坚实基础:

  • <p:library>包含步骤声明以提供可重用的步骤库
  • <p:declare-step>定义一个步骤及其函数签名,通常位于一个 <p:library> 元素中
  • <p:import>通过统一资源标识符(Uniform Resource Identifier,URI)将任何已声明的管道或库导入到当前管道中

Xproc 辅助元素主要是 Xproc 步骤的子节点,处理步骤绑定、简化步骤配置等任务。这些元素包括:

  • 输入和输出:这些元素定义可以绑定到其他步骤的输入或输出的端口,并定义 XML 文档的流。另外,还可以(直接在 Xproc 文档中)定义 XML 文档内联或者通过外部 URI 导入文档。
  • 选项:选项是配置步骤的主要机制,带有 <p:with-option> 元素或作为步骤实例中的一个名称-值属性。注意,选项是步骤的函数签名的一部分,它们的名称都是不变的。
  • 变量:变量和复合步骤一起使用,定义在复合步骤子管道中使用的 Xpath 变量。
  • 参数:正如 <p:declare-step> 所定义的,与选项、变量不同,参数的名称是在运行时计算出来的,与函数签名无关。Xproc 的最重要的方面也许是标准 Xproc 库中定义的第 30-40 步,这些步骤被划分为必需和可选的步骤集合。

Xproc 真正的强大之处在于必需和可选步骤的标准库,这些步骤执行广泛的任务,例如:

  • XSLT、XQuery、XInclude 处理
  • 模式验证(DTD、RelaxNG、Schematron、XML 模式)
  • XML 更新操作,例如插入或删除 XML 元素或属性
  • XML 存储和检索
  • 对 XML 进行包装、解包、转义(escape)和转回(unescape)
  • HTTP 请求
  • 执行本机命令

下面简要概述 Xproc 标准库中包含的各个步骤:

  • 必需步骤:
    • <p:add-attribute>向匹配元素集中添加一个属性。
    • <p:add-xml-base>添加或纠正元素的 xml:base 属性。
    • <p:compare>比较两个文档是否相等。
    • <p:count>统计源输入中的文档数目。
    • <p:delete>从源输入中删除由匹配模式指定的项。
    • <p:directory-list>在输出结果中枚举目录列表。
    • <p:error>生成一个动态错误。
    • <p:escape-markup>对源输入进行转义。
    • <p:http-request>与由基于 HTTP 的国际化资源标识符(IRI)标识的资源进行交互。
    • <p:identity>将输入源精确复制到结果输出。
    • <p:insert>在源输入中插入一个 XML 选择。
    • <p:label-elements>为每个匹配元素创建一个标签,并在属性中存储标签值。
    • <p:load>载入一个由 IRI 指定的 XML 资源并提供为结果输出。
    • <p:make-absolute-uris>将源输入中的元素或属性值转换为结果输出中的绝对 IRI 值。
    • <p:namespace-rename>重命名名称空间声明。
    • <p:pack>合并两个文档序列。
    • <p:parameters>将一组参数作为 c:param-set XML 文档在结果输出中提供。
    • <p:rename>重命名元素、属性或处理指令。
    • <p:replace>替换匹配元素。
    • <p:set-attributes>设置匹配元素上的属性。
    • <p:sink>接受源输入但不生成结果输出。
    • <p:split-sequence>将一个序列分解为两个序列。
    • <p:store>将源输入的序列化版本存储到 URI 中。
    • <p:string-replace>在源输入上执行字符串替换。
    • <p:unescape-markup>对输入源进行转回。
    • <p:unwrap>用子元素替换匹配元素。
    • <p:wrap>用一个新的父元素包装源文档中的匹配节点。
    • <p:wrap-sequence>生成一个新的文档序列。
    • <p:xinclude>对输入源应用 Xinclude 处理。
    • <p:xslt>对输入源应用 XSLT 1.0 或 2.0 版样式表。
  • 可选步骤:
    • <p:exec>对输入源使用外部命令。
    • <p:hash>为一些值生成消息摘要或数字指纹。
    • <p:uuid>生成一个全球统一标识符(Universally Unique Identifier,UUID)。
    • <p:validate-with-relax-ng>用 RelaxNG 模式验证输入的 XML。
    • <p:validate-with-schematron>用 Schematron 模式验证输入的 XML。
    • <p:validate-with-xml-schema>用 XML 模式验证输入的 XML。
    • <p:www-form-urldecode>将 x-www-form-urlencoded 字符串解码为一组 Xproc 参数。
    • <p:www-form-urlencode>将一组 Xproc 参数值编码为 x-www-form-urlencoded 字符串。
    • <p:xquery>应用 XQuery 1.0 版进行查询。
    • <p:xsl-formatter>呈现 XSL 1.1 版文档(与 XSL-FO 一样)。

从现有管道创建新的步骤非常容易。如果您喜欢,甚至可以使用扩展步骤创建第三方库来扩充 Xproc 处理器本身的功能。

注意:由于规范的制定还在进行中,标准库部分随时都可能改动。因此,建议参考当前 WD(参见 参考资料)中针对指定细节的最新定义。





回页首


示例管道

清单 1 展示了一个包含单个步骤的 Xproc 管道,该步骤对 XML 文档应用 XSLT 操作。


清单 1. 简单的隐式管道
                
<p:pipeline xmlns:p="http://www.w3.org/ns/xproc" name="xslt-example">
	<p:xslt>
		<p:input port="stylesheet">
			<p:document href="mystylesheet.xslt"/>
		</p:input>
	</p:xslt>
</p:pipeline>

Xproc 管道接受 0 个或多个 XML 文档作为输入,生成 0 个或多个 XML 文档作为输出。清单 1 中的 Xproc 代码仅包含一个 <p:pipeline> 顶层元素和一个 <p:xslt> 步骤。传入到 Xproc 处理器的标准输入中的 XML 文档由 <p:xslt> 步骤进行处理,该步骤应用 mystylesheet.xsltmystylesheet<p:input>/<p:document> 元素定义)对 XML 文档进行 XSLT 处理。

由于只有一个步骤,其结果被存放在整个管道的结果端口上,该端口通常会将 XML 文档输出到标准输出。图 1 显示了该过程,概括了 XML 文档从源流到结果端口的路径。


图 1. 简单管道的逻辑流
简单管道的逻辑流

端口之间的这些连接称为步骤绑定,它们控制 XML 文档处理流。这些绑定可以通过隐式或显式方式定义。在 清单 1 的例子中,绑定是隐式的,带有 Xproc 内部默认机制所规定的处理流。

清单 2 展示了带有显式步骤绑定、具有相同功能的管道。


清单 2. 简单显式管道
                
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" name="xslt-example">

	<p:input port="my-source" primary="true" sequence="false"/>
	<p:output port="my-result" primary="true" sequence="false">     
		<p:pipe step="step1" port="result"/>
	</p:output>

	<p:xslt name="step1">
		<p:input port="source">       
			<p:pipe step="xslt-example" port="my-source"/>     
		</p:input>
		<p:input port="stylesheet">
			<p:document href="mystylesheet.xslt"/>
		</p:input>
	</p:xslt>

</p:declare-step>

清单 1 中,我使用了 <p:pipeline>,它隐式声明了一个源输入和结果输出端口。现在采用 <p:declare-step> 意味着我必须显式定义这些端口,并在连续的同级步骤之间声明步骤绑定。这些绑定和端口概括如下:

  • 顶层 my-source 输入端口将接收到所有标准输入。
  • 顶层 my-result 输出端口将接收到 step1 结果端口的结果并将它们放在标准输出上。
  • step1 源输入被绑定到 my-source 输入端口。

很难使用只有单个步骤的管道示范步骤之间的步骤绑定;因此,我创建了一个特殊的例子来展示多个 Xproc 步骤和逻辑结构。清单 3 展示了一个更有代表性的 Xproc 的例子,其中包含多个步骤以及一些条件逻辑步骤。


清单 3. 复杂管道
                
<p:pipeline name="mypipeline" type="myexample" xmlns:p="http://www.w3.org/ns/xproc">
	<p:xinclude name="step1"/>
	<p:choose name="step2">
		<p:when test="/*[@version &lt; 2.0]">
			<!-- subpipeline //-->
			<p:validate-with-xml-schema name="step2a1">
				<p:input port="schema">
					<p:document href="newer-schema.xsd"/>
				</p:input>
			</p:validate-with-xml-schema>
		</p:when>
		<p:otherwise>
			<!-- subpipeline //-->
			<p:validate-with-xml-schema name="step2b1">
				<p:input port="schema">
					<p:document href="older-schema.xsd"/>
				</p:input>
			</p:validate-with-xml-schema>
		</p:otherwise>
	</p:choose>
	<p:for-each name="step3">
		<p:iteration-source select="//div"/>
		<!-- subpipeline //-->
		<p:string-replace name="step3a1">
			<p:option name="match" value="//span[@class=’css1’]"/>
			<p:option name="replace" value=""/>
		</p:string-replace>
	</p:for-each>
	<p:wrap-sequence name="step4">
		<p:option name="wrapper" value="document"/>
	</p:wrap-sequence>
</p:pipeline>

该管道可概括如下:

  1. 从标准输入设备输入 XML 文档。
  2. 执行 <xinclude> 处理(step1)。
  3. 在(step2)新模式(step2a1)或旧模式(step2b1)之间进行选择和验证。
  4. 提取每个(step3)HTML <div> 元素,执行字符串替换操作(step3a1)。
  5. 使用 <document> 元素包装 <div> 元素的最终序列(step4)。
  6. 将 XML 文档输出到标准输出。

步骤可以定义其他输入和输出端口来处理非 XML 文档,但是只有 XML 文档(正如 XML infoset 中所描述的)能够在基本输入输出端口之间传送。

在本例中,我用了三种 Xproc 步骤,步骤类型在工作流图中用矩形表示,如 图 2 所示。


图 2. 复杂管道的逻辑流
复杂管道的逻辑流

p:pipeline 复合步骤

最大的矩形代表整个 <p:pipeline>,它本身可以作为一个步骤被调用。因为它包含子管道,所以是一个复合步骤。

p:choose 多容器步骤

<p:choose> 步骤包含两个子管道,因此称为多容器步骤。它根据 <p:when> Xpath 表达式的赋值确定选择哪个子管道。

p:for-each 复合步骤

<p:for-each> 步骤包含由一个步骤组成的单个子管道,因此,它是一个复合步骤。

原子步骤

大多数 XProc 步骤都是原子步骤,它们对 XML 文档执行特定的操作。例如 <p:xinclude><p:validate-><p:string-replace><p:wrap>





回页首


Xproc 开发的考虑因素

在 Xproc 规范的发展过程中,WG 必须解决一些问题:

  • 名称空间:Xproc 处理 XML 文档,这意味着需要执行大量操作,处理器必须跟踪文档中的名称空间。例如,考虑一下 Xproc p:unwrap 步骤,它删除文档的顶层元素。如果此步骤删除的顶层元素恰好具有名称空间 xmlns 声明,那么必须让 Xproc 应用一个修复 操作,以确保将移除的名称空间声明复制到最终 XML 文档的子元素中,注意不要覆盖其他有效的名称空间声明。

    WD 包含一个非标准化的 “Section E. Guidance on Namespace Fixup”,尝试概括了一个处理器必须处理的内容。

  • XSLT 和 XPath 版本:Xproc 工作的时间选择说明它在 XPath 和 XSLT 版本之间的采用周期中找到了自己的定位。我想当我们开始使用 Xproc 时,将会看到 Xproc 出色地解决了关于支持多种 Xpath 和 XSLT 版本的棘手问题。
  • 选项、变量和参数:处理过程涉及的选项、变量和参数太多了。我想很多人都会同意我的观点,那就是单个实体就足够完成任务。
  • 流:我想 WG 在早期的 Xproc 决策中一定非常重视这个需求。试想一下,Xproc 控制的 XML 技术优势不会完全成为标准流。这看起来就像早期的优化,尤其是在 MapReduce 和并行化技术占主导地位的环境中。




回页首


目前的状态

同任何 W3C 规范一样,Xproc 在语法和语义方面都有了很大的变化(参见 参考资料)。最新的 WD(于 2008 年 5 月 1 日发布)进行了重大改进,它去除了以前的草案决策中的一些混淆内容,同时支持 Xpath 和 XSLT 第 1 和第 2 版。

当前的 WD 也进行了重大改进,它重新编写了规范,诠释了 <p:option> 元素现在的一些概念。例如 <p:option> 现在只用于一个步骤的函数签名(仅限 <p:declare-step>);当设置一个选项值时,将 <p:with-option> 在步骤实例自身的内部使用。另外,添加了 <p:variable/> 元素来存放计算值,具体来讲,用于与复合步骤结合使用。

对选项,参数和变量来说,最有趣的变化是移除了值属性;现在值是一个 Xpath 表达式的计算结果,该表达式由一个选择属性定义。清单 4p:with-option 为例阐明了该过程。


清单 4. 将 p:with-option 与 Xpath 表达式结合使用的例子
                			
<ex:someStep>
	<p:with-option name="some-option-name" select="'some value'"/>
</ex:someStep>

使用 Xpath 表达式定义选项的简单值现在变得有点繁琐(例如,需要使用嵌套的双引号(")和单引号('))。语法简写(参见 清单 5)作为首选的方法被保留,可以在步骤元素上使用名称-值属性定义选项。


清单 5. 使用语法简写设置选项
                			
<ex:stepType option-name="some value"/>

所有这些变化使规范的条理更加清晰,但是 Xproc 词汇表变得更加庞大(<p:variable><p:with-option><p:with-param> 等)。

最后需要提及的一个重大变化是,现在你必须始终使用 <p:declare-step/> 来声明新的步骤。这个变化给用户增加了一些认知压力,现在他们必须考虑一个步骤实例 而不是步骤的声明(位于一个库或管道中)。在 Xproc 中,在解释步骤 元素的时候引入过多的概念可能会带来潜在的局限性。我认为 WG 现在对概念进行划分是一个实用的决策。





回页首


结束语

对 XML 技术专家而言,重要的是提醒自己一些领域的开发人员并不使用 XML。当一些人问道,“为什么我需要 Xmroc” 时,我通常的回答是 “Xproc 与平台无关,只要能够运行兼容 XProc 的处理器的地方就可以运行 Xproc”。然而,如果你已经在使用 XML 文档和技术,您可能会使用其他方法 (XSLT、Apache Ant、Apache Cocoon 站点地图 和 Jelly 等)来效仿 XProc,你将会很高兴地看到 Xproc 处理器的到来。

注意:虽然所有 Xproc 实现都还不能用于生产,但一些实现已经在开发过程中。请参阅 参考资料 获得更多信息。

随着 XML 渗透到各个计算领域,如果能够找到像 Xproc 这样的独立且容易理解的方法来处理日益膨胀的 XML 应用领域,那么这种方法必定是一种革命性的技术。Xproc 标准库,连同可以编写自己的第三方步骤库的扩展功能,为现有和未来的 XML 处理器带来了强大的动力。因此,您无需让工作流去适应变化多端的特定技术,现在可以将自己的处理定义为 XML 文档上的一系列操作。

在接下来的几个月中,Xproc 将会进入第二次 Last Call,这意味着您会在 2008 年末看到一个 W3C 建议。



参考资料

学习

获得产品和技术
  • Xproc 实现列表:查看当前正在开发的 Xproc 实现。

  • Smallx:探究 Smallx。根据其开发人员描述,“它是为处理 XML infoset 而开发的一个库和工具集。它有两个不同的特性,一个是 infoset 实现允许文档流,另一个是 infoset 的处理可以使用管道概念来完成。”

  • Sxpipe:尝试使用简单 XML 管道(Simple XML Pipelines,sxpipe)构建简单的 XML 文档处理模型,并选择计算组件的顺序。

  • Apache Ant:获得更多相关信息并下载这个基于 Java™ 的构建工具。

  • Apache Cocoon:下载此框架并了解这个围绕关注分离概念构建的 Web 开发框架的更多信息。

  • Jelly:使用该工具把 XML 代码转换为可执行文件。

  • 用于产品评估的 IBM 试用软件:使用可从 developerWorks 直接下载的 IBM 试用软件构建您的下一个项目,这些软件包括来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。


讨论


关于作者

Photo of Jim Fuller

作为一名专业开发人员,15 年来 Jim Fuller 一直与出生地美国和英国的一些著名软件公司进行合作。他参与编写了很多与技术相关的书籍,并经常发表演讲和撰写关于 XML 技术的文章。他是 XML Prague 的创始委员之一,并在负责研究 EXSLT 的小组中任职。他在业余时间中研究 XML databases 和 XQuery。Jim 是多家公司 (FlameDigitalWebcomposite s.r.o.) 的技术总监,可以通过 jim.fuller@webcomposite.com 与他联系。




对本文的评价










回页首


Adobe、Adobe 徽标、PostScript 和 PostScript 徽标是 Adobe Systems Incorporated 在美国和/或其他国家的商标或注册商标。 IBM、IBM 徽标、ibm.com、DB2、developerWorks、Lotus、Rational、Tivoli、WebSphere 和 pureXML 是 IBM Corporation 在美国和/或其他国家的商标。 Java 和所有基于 Java 的商标是 Sun Microsystems, Inc. 在美国和/或其他国家的商标。 UNIX 是 The Open Group 在美国和其他国家的注册商标。 其他公司、产品或服务的名称可能是其他公司的商标和服务标志 其他公司、产品或服务的名称可能是其他公司的商标或服务标志。

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