级别: 初级 Brian M. Carey, 信息系统咨询师, Carey Development Corporation
2009 年 11 月 09 日 XML 文档通常采用 DTD(较少)或 XML 模式(较多)进行验证。最近,诞生了一种新的称为内容组装机制(Content Assembly Mechanism,CAM)的技术。它由结构化信息标准促进组织(Organization for the Advancement of Structured Information Standards,OASIS)推出。CAM 代表着 XML 模式又前进了一步,因为它在定义 XML 文档的语义和与实际数据内容相关的业务规则方面提供了更多的灵活性。在本文中,我们大致介绍一下 CAM,包括它所带来的好处。
CAM 的前辈
如上所说,CAM 代表着验证 XML 文档的最新技术。当然,这就意味着以前也有验证 XML 文档的技术。
 |
常用缩写词
- CCTS (Core Components Technical Specification):核心组件技术规范
- DTD (Document Type Definition):文档类型定义
- IT (information technology):信息技术
- OWL (Web Ontology Language):Web 本体语言
- XPath (XML Path Language):XML 路径语言
- XML (Extensible Markup Language):可扩展标记语言
- XSD (XML Schema Definition):XML 模式定义
|
|
最早的技术称为文档类型定义,即 Document Type Definition (DTD)。随着新兴技术的推出,它的局现性显现出来。它推动了 XML 文档结构的验证,但在语义方面表现不够。它还使用有些拙笨的语法来定义有效的 XML 结构。
DTD 后来被 XSD 所取代,即 XML Schema Definition(XML 模式定义)。这是一种更为强大的验证 XML 文档的方式。首先,其语法类似于 XML 文档本身。其次,它改进了对语义的支持。最近几年,前沿技术人员已经选择使用 XSD 来验证其 XML 文档,逐渐抛弃了 DTD。
走近 CAM
技术发展史表明,人们一直在寻找更好的方式来解决技术问题。XML 验证技术也毫不例外。在用于验证 XML 文档的各种技术中,CAM 代表着最新和最完善的技术。
CAM 由 OASIS 标准组织推出。该组织推出了很多规范,最有名的是有关 Web 服务的规范和电子商务 XML(electronic business Extensible Markup Language, ebXML)。
CAM 相比其前辈,要更加灵活和强大。与 XSD 不同,它不会将数据结构与业务规范绑定在一起。它还提供内容驱动的验证,这在 XSD 和 DTD 中是不具备的。
对于大多数熟悉 XML 的人来说,CAM 要比 XSD 或 DTD 更易于学习。这是因为,在定义结构方面,CAM 文档的格式非常类似于一个 XML 实例。并且,在定义业务规范方面,CAM 使用了大家熟悉的 XPath。
CAM 模板的结构
从 清单 1中可以看到,CAM 模板的结构一点也不复杂。
清单 1. CAM 模板的结构
<as:CAM xmlns:as="http://www.oasis-open.org/committees/cam"
CAMlevel="1"
version="1.0">
<as:Header />
<as:AssemblyStructure />
<as:BusinessUseContext />
</as:CAM>
|
根元素 CAM定义了整个模板本身使用的名称空间以及 CAM 的层次和版本。
Header元素提供了有关验证文档的特定信息。许多子元素(未给出)是顾名思义的:Description、Owner、Version和 DateTime。
AssemblyStructure元素定义了 XML 文档实例的实际结构。这就是 CAM 和 XSD 的区别之一。AssemblyStructure元素提供针对 XML 文档结构的验证,但不包含有关语义的任何信息。
最后,BusinessUseContext元素提供了以前的元素所缺少的业务规则。如何实施这些业务规范呢?这是一个非常好的问题,不过您首先应该熟悉 CAM 是如何定义结构的。
CAM 如何定义结构
清单 2给出了 CAM 如何定义一个简单购买订单的结构。
清单 2. 简单购买订单的 CAM 结构
<as:AssemblyStructure>
<as:Structure ID="myPO" taxonomy="XML">
<PurchaseOrder>
<ShippingAddress>
<Name>%string%</Name>
<Street>%string%</Street>
<City>%string%</City>
<State>%string%</State>
<Zip>%string%</Zip>
</ShippingAddress>
<ShipDate>%DD-MM-YYYY%</ShipDate>
<comment>%string%</comment>
<LineItems>
<LineItem>
<ItemName>%string%</ItemName>
<Quantity>%1%</Quantity>
<Price>%54321.00%</Price>
<Comment>%string%</Comment>
</LineItem>
</LineItems>
<TotalPrice>%54321.00%</TotalPrice>
<ShippingMethod>%string%</ShippingMethod>
</PurchaseOrder>
</as:Structure>
</as:AssemblyStructure>
|
在阅读 清单 2时,注意所定义的 XML 文档的结构,它几乎就是一个 XML 实例。从这一方面来讲,大多数 IT 专业人员都认同,对于已经了解 XML 语法的人来说,CAM 比 XSD 更易于阅读。实际上,CAM 就是作为 XML 实例来描述的,但带有一些不相关的内容,这一点我会在下面解释。
Structure元素是实际结构定义的父级。它有一个 ID属性,用于识别此特殊结构。taxonomy属性的唯一当前可用值是 XML。
注意,大多数元素包括用百分号 (%) 分开的值。它只是将要包含在 XML 实例中的实际内容的占位符。相比于给出任何验证逻辑而言,这样做只是为了使文档更易于理解。有些人在构建 CAM 模板时,实际上会在元素中采用一些示例值,而不是使用 清单 2中所示的通用值。如何更好地使用占位符取决于开发人员的习惯。
您已经了解如何在 CAM 中定义结构,现在我们来了解一下如何实施业务规则。
CAM 如何实施业务规则
下面是一个这样的例子:XPath。
是的,没错。一个 XPath 的例子。
现在我们可以看到 CAM 相比较早验证技术的另一项优势。它使用大多数 XML 技术人员已经用于实施业务规则的语法。对于这些人来说,他们不必学习另一种语言即可在其应用程序中实现 CAM 验证。
清单 3是一个 BusinessUseContext元素的例子。
清单 3. 利用 CAM 实施业务规则
<as:BusinessUseContext>
<as:Rules>
<as:default>
<as:context>
<as:constraint action="makeRepeatable(//PurchaseOrder/LineItems/LineItem)"/>
<as:constraint action="makeOptional(//LineItem/Comment)"/>
<as:constraint action="setLength(//ShippingAddress/State,2)"/>
<as:constraint action="setDateMask(//PurchaseOrder/ShipDate,DD-MM-YYYY)"/>
<as:constraint action="setNumberMask(//LineItem/Quantity,###)"/>
<as:constraint action="setNumberMask(//LineItem/Price,###.##)"/>
<as:constraint action="setNumberMask(//PurchaseOrder/TotalPrice,###.##)"/>
<as:constraint condition="//PurchaseOrder/TotalPrice > 100"
action="makeOptional(//PurchaseOrder/ShippingMethod)">
</as:context>
</as:default>
</as:Rules>
</as:BusinessUseContext>
|
对于有经验的 XML 开发人员,应该很容易看懂这个结构。这不仅仅因为约束使用了 XPath,还因为验证规则使用了标准英语来命名。这就是 CAM 的魅力所在。
这些规则本身在 context元素中定义。每个规则是 constraint子元素之一的 action参数。
注意第一个规则:makeRepeatable(//PurchaseOrder/LineItems/LineItem)。顾名思义,它告诉验证器,LineItems元素的 LineItem子元素是可重复的。这表示可以有多个这样的子元素,这完美地解释了在一个典型购买订单中可以包含多个不同的条目。
下一条规则是关于 Comment元素的。此规则声明,注释是可选的。换句话说,XML 文档在带有空的 Comment元素时是有效的。
下一条规则用于限制 State元素的最长字符数。在本例中,最大长度是 2,这表示美国各个州的邮政缩写。
下一条规则是日期格式。这里,使用了格式 DD-MM-YYYY,当然您也可以使用其他格式。在本例中,有效的日期应该类似于 03-03-2009,表示 2009 年 3 月 3 日。
下一条规则是 Quantity元素的格式。在本例中,该元素的内容必须是匹配 ###掩码的数字。换句话说,购买订单中的条目如果 Quantity元素是四位数字,则认为是无效的。按此规则,购买订单不能包含同一产品订购数量超过 999 的条目。
接下来的两条规则,Price和 TotalPrice,类似于上一条规则。与 Quantity一样,它们受到数字掩码的约束。不同之处在于,这里的数字掩码允许小数点。这是因为这两个元素是美元值,可以包含代表分的小数值。
最后,还有一个特别重要的规则,因为它引入了内容驱动的约束 (context-driven constraint)。确切含义是什么呢?它是一个约束,可以验证基于某些元素内容的 XML 文档。在本例中,如果购买订单的总价格超过 $100,则 XML 文档的 ShippingMethod元素可以是空的。否则,它不能是空的。这里适用的业务规则是,总价超过 $100 的订单将获得免费配送。对于总价少于 $100 的订单,文档必须指定一种配送方法。
小结
清单 4给出了利用上面介绍的片段组装起来的整个 CAM 文档。
清单 4. 完整的 CAM 文档
<?xml version='1.0'?>
<as:CAM CAM level="1" version="1.0"
xmlns:as="http://www.oasis-open.org/committees/cam" >
<as:Header>
<as:Description>Simple Purchase Order</as:Description>
<as:Owner>developerWorks</as:Owner>
<as:Version>0.1</as:Version>
<as:DateTime>2009-07-07T12:00:00</as:DateTime>
</as:Header>
<as:AssemblyStructure>
<as:Structure ID="myPO" taxonomy="XML">
<PurchaseOrder>
<ShippingAddress>
<Name>%string%</Name>
<Street>%string%</Street>
<City>%string%</City>
<State>%string%</State>
<Zip>%string%</Zip>
</ShippingAddress>
<ShipDate>%DD-MM-YYYY%</ShipDate>
<comment>%string%</comment>
<LineItems>
<LineItem>
<ItemName>%string%</ItemName>
<Quantity>%1%</Quantity>
<Price>%54321.00%</Price>
<Comment>%string%</Comment>
</LineItem>
</LineItems>
<TotalPrice>%54321.00%</TotalPrice>
<ShippingMethod>%string%</ShippingMethod>
</PurchaseOrder>
</as:Structure>
</as:AssemblyStructure>
<as:BusinessUseContext>
<as:Rules>
<as:default>
<as:context>
<as:constraint action="makeRepeatable(//PurchaseOrder/LineItems/LineItem)"/>
<as:constraint action="makeOptional(//LineItem/Comment)"/>
<as:constraint action="setLength(//ShippingAddress/State,2)"/>
<as:constraint action="setDateMask(//PurchaseOrder/ShipDate,DD-MM-YYYY)"/>
<as:constraint action="setNumberMask(//LineItem/Quantity,###)"/>
<as:constraint action="setNumberMask(//LineItem/Price,###.##)"/>
<as:constraint action="setNumberMask(//PurchaseOrder/TotalPrice,###.##)"/>
<as:constraint condition="//PurchaseOrder/TotalPrice > 100"
action="makeOptional(//PurchaseOrder/ShippingMethod)">
</as:context>
</as:default>
</as:Rules>
</as:BusinessUseContext>
</as:CAM>
|
如上所示,清单 4比清单 2和 3合起来还多一点。添加了 Header元素,它用于识别有关此特定验证文件的信息。在本例中,添加了一段简单的描述、所有者和版本和文档日期。
虽然在 清单 4中没有给出,Header元素还可以包含其他参数。XML
文档的验证随参数值的不同而不同。例如,如果一个名为 noMoreThan10LineItems的参数设置为 true,则 CAM 文档将实施在整个订单中不超过 10 个 LineItem元素的业务规则。这是 CAM 在实施验证时多么强大和多么灵活的一个例子。这里的好处在于,您只需将该参数更改为 false即可取消该规则。
CAM 相比其竞争对手的优势
显然,某项技术是新的,并不代表它是有用的,或是比其前辈提供更高的投资回报。不过,CAM 相比其竞争对手,具有多项显著的优势。
首先,CAM 将结构与业务规则分离开来。这是整个软件开发的一种递归模式,根本不仅仅限于 CAM。例如,分布式对象开发环境中的模型 - 视图 - 驱动器 (MVC) 模式将模型与视图和控制器分离开来。与 CAM 不同的是,XSD 将结构和业务规则紧密耦合在一起,这导致了更昂贵的维护开销。
CAM 还支持内容驱动的验证。换句话说,CAM 识别基于某些元素或属性的动态结构。因此,如果元素 X 包含某个值,业务规则应用于元素 Y。如果元素 X 包括另一个值,该业务规则可以应用于元素 Z。 这在 清单 3的最后一个规则中说明了。在该例中,购买订单文档若总价超过 $100 则不需要指定配送方式,因为对于这种订单是免费配送的。CAM 的前辈不易实现这种复杂的验证。
在 CAM 中分析规则集和结构更加容易。结构就是一个 XML 实例,采用常用的树格式表示,因此人类及计算机更易于阅读。用于实施业务规则的语法同样很直观:makeRepeatable、makeOptional、setLength等都不难理解。还有,虽然规则和结构是分离的,但它们都在同一文档中,很容易获得整体验证需求的大致了解。另一方面,XSD 需要理解一整套新的非直观的定义,比如 complexType(它是什么意思呢?),并且它不易分析出来。
坚定“不必学习任何新东西”的理念,CAM 使用了 XPath。上面已经提到,这是一种对某些元素实施业务规则的语言。不仅仅因为 XPath 很直观且易于学习,还因为它易于被大多数 XML 技术人员所理解。这使得向 CAM 的过渡变得更容易,因为总体上来说,业务逻辑验证不需要 XML 开发人员学习任何新内容。XSD 语法一点也不像 XPath。
CAM 超过 XSD 的另一项优势在于,利用 CAM 更容易满足本地化需求。使用 XSD 时,枚举是静态的,因此无法做到上下文感知。然而,利用 CAM,您可以基于上下文值应用特定枚举。在新兴的全球市场环境下,这种简化验证的需求应该是自成一体的。
CAM 模板还支持下一代面向服务的架构 (Service-Oriented Architecture,SOA)。CAM 支持业务流程技术,如 Business Process Execution Language (BPEL)、Business Process Specification Schema (BPSS) 和 Business Process Modeling Notation (BPMN) 建模工具。下面引用 Wiki 上的话:“为了完善 SOA,CAM 具有扩展机制,可用于支持语义注册引用(如 ebXML-regrep)和元数据定义(如 CCTS 和 OWL),这是下一代 SOA 交换的关键。” 同样,CAM 由 OASIS 开发,因此,您可以确信,该组织将会确保 CAM 与它的其他标准是兼容的。
结束语
CAM 代表着最新一代的 XML 验证技术。它具有超出其前辈的各种优势。这些优势包括有关结构和业务逻辑的关注点分离、基于上下文的动态验证、与前沿技术的互操作性、低维护开销和易学性。CAM 由广受尊重的标准组织 OASIS 推出。
CAM 是一门新兴技术。因此,它还没有什么学习资料和实践经验。不过,它在初次发布时,肯定是相当强大的,它将是一种用于 XML 验证的更有效的方法。
这里可以断言的是,CAM 肯定会替代其前辈。
参考资料 学习
- OASIS CAM Wiki:学习有关 CAM 的更多知识。
- On XML Schema Tutorial:探索如何创建 XML Schema、XML Schema 为何比 DTD 更强大,以及如何在应用程序中使用 XML Schema。
- DTD Tutorial:了解如何使用 DTD。
- XML 入门(Doug Tidwell,developerWorks,2002 年 8 月):XML,即可扩展标记语言(Extensible Markup Language),已经从一个新名词发展成流行的电子商务技术。了解 XML 是什么,为什么开发它,以及它正在如何影响电子商务的未来。
- 验证 XML(Nicholas Chase,developerWorks,2003 年 8 月):验证文件和文档以确保数据满足完整性约束。了解什么是验证,以及如何针对 Document Type Definition (DTD) 或 XML Schema 文档检查一个文档。
- 为企业数据设计 XML 模式(Bilal Siddiqui,developerWorks,2006 年 10 月):学习使用 W3C XML Schema 特性来为生产管理设计数据格式。
- IBM XML 认证:了解如何成为 XML 以及相关技术的 IBM 认证的开发人员。
- XML 技术库:参见 developerWorks XML 专区,阅读广泛的技术文章和技巧、教程、标准和 IBM 红皮书。
- developerWorks 技术活动 和 网络广播:随时关注相关技术。
- 技术书店:浏览关于这些以及其他技术主题的书籍。
- developerWorks 播客:收听针对软件开发人员的有趣访谈和讨论。
获得产品和技术
讨论
关于作者  | 
|  | Brian Carey 是一位信息系统顾问,他的专长是 Java、Java Enterprise、PHP、Ajax 和相关技术。您可以在 Twitter 上了解 Brian Carey,网址是 http://twitter.com/brianmcarey。 |
对本文的评价
|