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

developerWorks 中国  >  XML  >

Schematron 抽象范式的灵活性

Schematron 的高级特性为 XML 模式带来了无限的可能性

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 中级

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

2004 年 10 月 01 日

如果对 XML 格式有一定的了解,并且知道不可能让与会的每个人都同意模式中的所有细节,那么请考虑 Schematron 抽象范式。Schematron 可能是最强大的 XML 模式语言(也许不仅仅是一种模式语言)。它的高级特性特别是抽象范式,允许使 XML 模式迅速适应不同的 XML 格式。这样就为 XML 模式带来了无限的可能性,包括限制 XML 格式,或者使其更具一般性和适应性。

ISO Schematron 是一种非常独特的 XML 模式语言,无论是结合其他模式语言或者单独使用都具有强大的功能。我曾经在教程“ Schematron 实用入门”中指出,Schematron 不仅仅是一种模式语言,而且是一种成熟的 XML 报告工具。本文将讨论 ISO Schematron 的一些高级特性,如果您对这种技术还不熟悉,建议您阅读那一教程。我将主要讨论变量赋值和抽象范式(pattern),这两种技术为 XML 模式设计带来了令人印象深刻的可能性。与上述那篇教程一样,本文中将使用 候选 XML表示 Schematron 模式调用的 XML 文件。

上述教程中曾经提到,严格地说, Schematron 是多种潜在的数据(包括 XML 和其他格式,如扁平文本或者数据库格式)访问方式的宿主语言。但是据我所知,所有 Schematron 执行基本上都使用 XPath 和 XSLT 作为查询语言,用于处理 XML。本文中就假定使用这样的一种执行。测试中使用的是 Scimitar ISO Schematron 工具箱(请参阅 Resources)。

Schematron 测试中的变量

Schematron 的很多思想受到 XSLT 的启发,包括使用变量简化代码。这一点对于约束数据类型非常有用,您需要验证 XML 中的某些文本是某种给定数据类型(如整数、日期、时间或 URL)的有效表示。通常,使用 XPath 检查源数据的词法特性冗长而复杂。明智地使用变量可以帮助简化。您可以按照通常的方式在 assertreport 元素的 test 属性中引用变量,比如 $var 。您可以在 Schematron 中使用 let 指令为变量赋值。清单 1 中的 Schematron 代码可以检验提供的钱数是否在 $10,000 和 $1,000,000 美元之间,允许使用千分符和美元符号。


清单 1. 验证钱数
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.ascc.net/xml/schematron">
  <title>Example of let</title>
  <pattern name="Nor too many nor too few dollars">
    <rule context="money">
      <!-- Remove dollar signs and US convention comma separators -->
      <let name="amount" value="number(translate(@amount, '$,', ''))"/>
      <assert test="$amount >= 10000 and $amount <= 1000000">
        Amount should range from ten thousand to one million dollars
      </assert>
    </rule>
  </pattern>
</schema>
  

XPath $amount >= 10000 and $amount <= 1000000 ,相对于 number(translate(@amount, '$,', '')) >= 10000 and number(translate(@amount, '$,', '')) <= 1000000 (Schematron 与 XSLT 一样,XPath 中的“<”必须转义),当然是一种改进。 let 指令的 value 属性在运行时使用封闭的 rule 中定义的上下文计算得到。清单 234都是非常简单的例子,对于 清单 1来说都是有效的,清单 56是无效的。


清单 2. 对清单 1 有效的代码
<money amount="$300,000.00"/>
  


清单 3. 对清单 1 有效的代码
<money amount="500,000"/>
  


清单 4. 对清单 1 有效的代码
<money amount="10000.00"/>
  


清单 5. 对清单 1 无效的代码
<money amount="$1,000.00"/>
  


清单 6. 对清单 1 无效的代码
<money amount="$3,000,000.00"/>
  

let 指令也可以出现在 rule 之外,直接作为 schemapatternphase 的孩子。如果 let 出现在 rule 之外,其 value 以文档根作为上下文节点计算得到。分阶段变量是参数化在不同阶段执行的测试的一种有趣方式。





回页首


Schematron 抽象范式

可以使用变量限制模式的参数化,就是说用规则之外的代码确定特定规则内的部分表达式。这种限制以如何在 XPath 中使用变量为中心。比如,如果希望参数化的是候选 XML 中的元素名,表达式可能就变得非常复杂(比方说必须使用谓词而不是简单的元素名测试)。

Schematron 抽象范式是一种更加灵活的参数化机制。抽象范式是一种特殊的范式,基本上被看作是一个模板。参数和 XPath 变量使用同样的语法(“$param”),但含义有所不同。Schematron 处理程序在用给定的值对参数进行文字串置换时,要执行一次预处理程序。抽象范式在模式编写中的重要用途在于,与候选 XML 中的精确词汇表相比,它更加灵活,强调 XML 中表达的一般概念。比方说,表格是 XML 格式中一种很常见的、增强可读性的组件。但是 XHTML 1.1 中的 Basic Table 模块和 DocBook 中的表格使用不同的词汇表。前者的词汇表源于 HTML,后者则基于 SGML 语言中的 CALS 表格标准。 清单 7 是一个抽象范式的例子,其中包含 XML 表格结构中的一些典型的约束。


清单 7. 表格中典型约束的抽象范式
  <pattern abstract="true" name="table">
    <rule context="$table">
      <assert test="$row">A table has at least one row</assert>
    </rule>
    <rule context="$row">
      <assert test="$cell">A table row has at least one cell</assert>
    </rule>
  </pattern>
  

属性 abstract="true" 表明这是一个抽象范式。范式中的查询(主要在 contexttest 属性中)可以包含 $table 这样的 参数引用。参数引用与 XPath 变量引用非常不同,它们完全是运行之前计算的串置换,使用给定的参数可以方便地改写查询。 如果不使用参数引用,抽象范式就与非抽象范式一样。清单 8 中使用抽象范式通过提供的参数值创建它的具体版本。


清单 8. 使用抽象数据类型
  <pattern name="xhtml-basic-table" is-a="table">
    <param formal="table" actual="table"/>
    <param formal="row"  actual="tr"/>
    <param formal="cell"  actual="td"/>
  </pattern>
  <pattern name="cals-table" is-a="table">
    <param formal="table" actual="ctable"/>
    <param formal="row"  actual="tbody/row"/>
    <param formal="cell"  actual="entry"/>
  </pattern>
  

清单 8 创建了两个范式,由 is-a 属性给定的抽象范式的具体实例,在该例中属性值为 is-a="table"param 元素提供了抽象范式中每个参数引用的值。比方说, 清单 8 中第一个 pattern 的第一个 param 具有属性 formal="table" ,表明它是为抽象范式中的参数实例 $table 赋值。这个值由 actual 属性(即 actual="table" )提供。它仅仅是置换文本,不作任何特殊处理。清单 9 是该范式的实例模型,是通过将 清单 8第二个范式的参数应用于 清单 7的抽象范式得到的。置换文本用蓝色突出显示。


清单 9. 参数已经解析的抽象范式实例模型
  <pattern name="cals-table">
    <rule context="
        
        table
				
        ">
      <assert test="
        
        tbody/row
				
        ">A table has at least one row</assert>
    </rule>
    <rule context="
        
        tbody/row
				
        ">
      <assert test="
        
        cell
				
        ">A table row has at least one cell</assert>
    </rule>
  </pattern>
      
      

允许使用只带一个 is-a 属性的范式指定参数,但是这种范式必须包含规则或者 let 元素。比如,如果希望通过添加范式来确保 CALS 表格中只能使用 tbody ,就不能简单地在 清单 8中的第二个范式增加一条规则,而必须为新增加的规则创建全新的、具体的范式。清单 10 是一个完整的 Schematron 例子,综合了清单 78中的代码,并增加了一个新的、仅用于 CALS 表格形式的具体范式。


清单 10. 使用抽象范式的 Schematron 的完整示例
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.ascc.net/xml/schematron">
  <title>Table abstract patterns</title>
 
  <pattern abstract="true" name="table">
    <rule context="$table">
      <assert test="$row">A table has at least one row</assert>
    </rule>
    <rule context="$row">
      <assert test="$cell">A table row has at least one cell</assert>
    </rule>
  </pattern>
  <pattern name="xhtml-basic-table" is-a="table">
    <param formal="table" actual="table"/>
    <param formal="row"  actual="tr"/>
    <param formal="cell"  actual="td"/>
  </pattern>
  <pattern name="cals-table" is-a="table">
    <param formal="table" actual="ctable"/>
    <param formal="row"  actual="tbody/row"/>
    <param formal="cell"  actual="entry"/>
  </pattern>
  <!-- special stand-alone pattern for CALS-specific table rules -->
  <pattern name="cals-table-extra">
    <rule context="ctable">
      <assert test="tbody">A table has a tbody</assert>
    </rule>
  </pattern>
</schema>
  





回页首


结束语

您已经看到,Schematron 抽象范式的基本机制非常简单。虽然如此,它却大大增强了 XML 模式的表达能力。常常遇到这样的情况,就模式的基本想法能够广泛达成一致,但是很难统一到具体的语法上来。比方说,表示订单可能有无数种 XML 格式,但是都需要有一些品名元素、交货地点等。 Schematron 抽象范式可以独立于订单格式所用的具体语法描述这类一般性概念。这种灵活性是 SGML 中的 Architectural Form 规范的优点之一。Architectural Form 是创建特殊 DTD 的一种方法,这种 DTD 允许 XML 名称的再映射。这种方法非常巧妙,但是也很复杂,很少有人能够充分地理解它并利用其强大的功能。Schematron 将其用于 XPath 查询从而提供了一种更加简单、更加灵活的方法。

如我在“ 技巧:将数据词典用于 XML 和 Web 服务大纲”一文中所述,如果再加上语义丰富的注释,还可以进一步增强 Schematron 抽象范式的表达能力。得到的模式更容易适应不同的语法,同时又保持 语义透明性,这是我在 Thinking XML 专栏中发明的一个词,即这样一种能力,无论信息使用了何种具体的语法,XML 系统都能正确解释。

即使眼下还用不上语义透明性,抽象范式也是一种很有用的工具。如果 XML 词汇表的用户分布在世界各地,而您希望提供元素名和属性名、受控词汇表等的本地化版本,可以考虑使用抽象范式。总之,这种 Schematron 设备将让您重新考虑更好的 XML 模式设计方式。



参考资料



关于作者

Uche Ogbuji 的照片

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




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?







回页首


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