将 Schematron 约束自动应用于 XForms 文档

发表于:2007-05-24来源:作者:点击数: 标签:Schematron应用于XForms约束自动
随着 XForms 规范第二版的发布,IBM alphaWorks 发布了一系列新的免费工具,包括 XML Forms Generator,从而帮助加快符合这个标准的表单 开发 。最近的更新允许将 Schematron 1.5 文档中定义的约束应用于生成的表单。Schematron 本身是一个 XML 标记,它为业
随着 XForms 规范第二版的发布,IBM alphaWorks 发布了一系列新的免费工具,包括 XML Forms Generator,从而帮助加快符合这个标准的表单开发。最近的更新允许将 Schematron 1.5 文档中定义的约束应用于生成的表单。Schematron 本身是一个 XML 标记,它为业务规则和数据关系提供了规范,这是 XML 模式不能提供的。XForms 本身提供了对 XML 模式的检验,而对 Schematron 约束的任何使用必须构建在表单本身中。目前开发组织正在努力将 Schematron 约束与 XForms 集成起来 —— 比如 Origo Standards, Ltd 构建的 Instance Validator 表单(参见 参考资料)—— 很自然,下一步是自动应用这些约束。

World Wide Web Consortium(W3C)开发的 XForms 标准用于表单数据的表示和收集。W3C Recommendation 声称,XForms 意图成为 “Web 的下一代表单”。Recommendation 本身声明,“通过将传统的 XHTML 表单分为三个部分 —— XForms 模型、实例数据和用户界面,它将表示从内容中分离出来,从而支持重用,提供强类型,减少与服务器的通信次数,提供设备独立性,减少对脚本编程的需要。”

XForms 文档提供一个数据模型,其中包含一个或多个 XML 实例文档。表单操纵实例文档并将 XML 提交到后端系统。因为 Schematron 本身是 XML,XForms 可以很容易地将它作为表单数据模型的一部分对待。

XForms 1.0 规范的第二版在 2006 年 3 月 14 日的发布是一个重要的里程碑。不久之后,alphaWorks 就提供了包含 Schematron 支持的 XML Forms Generator 更新。

XML Forms Generator 是什么?

XML Forms Generator 在表单开发方面提供了飞跃性进步。它快速自动地产生有效和功能性的表单,其中包含嵌入在 XHTML 文档中的 XForms 标记。表单生成过程的输入可以是有或没有 XML 模式的 XML 数据实例,也可以是 Web Services Description Language(WSDL)文档。

XML Forms Generator 是开放源码的 Eclipse 工作台的一个插件(见 参考资料),它是 2005 年 4 月在 alphaWorks 上首次发布的。参考资料 中有 XML Forms Generator 的 alphaWorks 页面的链接,可以在这个页面上进一步了解和安装这个工具。

什么是 Schematron?

XML 模式广泛用来静态地描述 XML 的结构和内容,它非常适合这个用途。但是,它在实例的动态分析方面功能有限。例如,在 XML 模式中,不能这样约束 XML 文档:“元素 A 和 B 的值的和必须等于 100。”

在 Schematron 中,可以轻松地指定这样的约束。与 XML 模式相似,Schematron 本身是 XML,因此自然地适合 XForms,XForms 本身是一个用于操纵 XML 数据的 XML 标记。Schematron 使用很小的标记集和 XPath 等熟悉的语法,因此它很容易学习和编写,但是也很强大。

国际标准化组织(ISO)正在对 Schematron 进行标准化;已经形成了一个规范草案(见 参考资料)。在目前,Schematron 1.5 已经被广泛采用,而且 XML Forms Generator 只处理 Schematron 1.5 文档。

Schematron 文档基本上是一组应用于 XML 数据的约束。可以以两种方式之一表达具体的 Schematron 约束:

  1. 作为断言,这意味着对应用于实例文档的特定条件进行测试。实例文档要想有效,所有断言的计算结果都必须是 true
  2. 作为报告,在这种情况下也对应用的条件进行测试。但是,测试的意义与断言的意义正好相反。如果测试结果是 true,那么文档将处于无效状态。

Schematron 允许将断言和报告一起分组在称为规则 的结构中,然后将这些规则一起分组在模式 中。

可以使用 XPath 指定测试条件,还可以指定应用测试条件的上下文。Schematron 作者还可以提供在违反条件时应用的文本。这些文本应该是人可阅读的,用来向正在操纵数据实例的最终用户进行说明。另外,这些文本也可以具有更强的技术性,从而向正在构造 XML 实例的 XML 开发人员指出 XML 实例必须符合给定 Schematron 文档中定义的约束。

在本文中,我们使用 清单 1 中的简单 XML 实例文档。


清单 1. 简单 XML 文档
            <?xml version="1.0"?>
            <root xmlns="http://www.example.org"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.example.org Simple.xsd">
            <A>100</A>
            <B>0</B>
            </root>

清单 1 中的 XML 实例文档引用一个称为 Simple.xsd 的模式,这个模式的内容见 清单 2


清单 2. 简单 XML 文档的 XML 模式
            <?xml version="1.0" encoding="UTF-8"?>
            <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.example.org"
            xmlns:ex="http://www.example.org"
            elementFormDefault="qualified">
            <xsd:element name="root" type="ex:rootType"/>
            <xsd:complexType name="rootType">
            <xsd:sequence>
            <xsd:element name="A" type="xsd:integer"/>
            <xsd:element name="B" type="xsd:integer"/>
            </xsd:sequence>
            </xsd:complexType>
            </xsd:schema>

清单 2 中的 XML 模式文档声明元素 A 和元素 B 的类型是 integer。但是,XML 模式无法定义对这两个元素的值的约束 —— 例如,它们的和等于 100。但是,在 Schematron 中很容易定义这个约束,见 清单 3


清单 3. 简单 XML 文档的 Schematron 定义
            <?xml version="1.0"?>
            <sch:schema xmlns:sch="http://www.ascc.net/xml/schematron">
            <sch:title>AB Example</sch:title>
            <sch:ns uri="http://www.example.org" prefix="ex" />
            <sch:pattern name="Our Only Pattern" id="pattern1">
            <sch:rule context="/ex:root" id="sum100">
            <sch:assert test="ex:A + ex:B = 100">
            The sum of the values of A and B must be 100.
            </sch:assert>
            </sch:rule>
            </sch:pattern>
            </sch:schema>

尽管目前对 Schematron 的介绍还很简短,但是您可以很容易地看出这个文档的作用。对于应用这个文档的任何 XML 数据,A 和 B 的和值必须等于 100,这是由惟一的 assert 元素的 test 属性中的 XPath 表达式声明的。

在 XML Forms Generator 中如何指定 Schematron 文档?

在 XML Forms Generator 中,使用 XML Forms Generator 首选项类别下面的全局首选项设置(Window > Preferences)指定在生成表单期间要处理的 Schematron 文档。

可以用两种操作之一指定 Schematron 文档。在后面会深入讨论这些操作,但是目前只需知道能够选择这些选项之一来激活 Schematron schema location 首选项。然后可以选择 Browse 来指定要应用于生成的表单的模式文档(见 图 1)。


图 1. XML Forms Generator 中的 Schematron 处理选项
XML Forms Generator 中的 Schematron 处理选项

有时候,Schematron 约束包含在 XML 模式文档中,常常在 XML 模式的 appinfo 元素中。但是 XML Forms Generator 只处理单独的 Schematron 文档。

如何将约束应用于表单?

在 XForms 中,可以为实例数据指定约束,必须满足约束才能提交此数据。Schematron 首选项页面中的第一个选项 Apply constraints found in a schematron schema 让 XML Forms Generator 将 Schematron 文档中定义的约束应用于它生成的任何 XForms 文档。

XForms 将约束绑定到实例数据,从而应用约束。如果对 清单 1 中的数据运行 XML Forms Generator,使用 清单 3 中的 Schematron 文档并选择 Apply constraints 选项,那么会产生具有 清单 4 中的 XForms 绑定的表单。


清单 4. 对表单提交进行约束的 XForms 绑定
            <xforms:bind nodeset="instance('instance_model_root')"
            constraint="instance('instance_model_root')[ex:A + ex:B = 100]"/>

这个 XForms 绑定元素有两个属性 nodesetconstraint,它们都是 XPath 表达式。在 清单 4 中,nodeset 属性描述实例文档中将受到约束的节点。在这个示例中,XForms instance() 函数指出命名的实例中的所有数据都受到约束。constraint 属性包含一个布尔表达式,它定义数据必须符合的条件。这个 XPath 表达式实施在 Schematron 文档中看到的约束,即元素 A 和 B 的和值必须等于 100。

如果这个表达式的计算结果不是 true,那么 nodeset 属性指定的数据(在这个示例中是整个文档)就是无效的,不能提交。图 2 显示 XML Forms Generator 生成的简单表单在 Mozilla Firefox 中的样子。


图 2. Firefox 中的表单
Firefox 中的表单

图 2 中,如果修改 A 和 B 的值,让它们的和不等于 100,那么应用于这个表单的约束就会起作用。在这种情况下,按 Submit 按钮时什么事情也不会发生,因为绑定使当前数据成为无效的。另一方面,如果提供了可接受的值,那么按 Submit 按钮就会导致提交 XML 数据。

如何为被违反的条件提供详细消息?

XForms 还可以动态地隐藏或显示控件,这同样要在数据上使用绑定,但是这一次使用称为 relevant 的模型项属性(XForms 规范详细解释了 XForms 模型项属性,见 参考资料)。XML Forms Generator 首选项(图 1)中提供的另一个 Schematron 选项 Generate validation message outputs from schematron messages 利用这种机制有条件地显示 Schematron 文档中为各个断言和报告指定的消息。

在这个示例中,希望根据相关 Schematron 断言或报告指定的测试来分别控制每个消息的显示。因此,每个断言或报告有自己的相关性绑定,就像 清单 5 中这样。


清单 5. 将相关性应用于 Schematron 消息
            <xforms:bind id="pattern_Our Only Pattern_rule_1_assert_1"
            nodeset="instance('instance_model_root_schematron')/
            sch:pattern[@name='Our Only Pattern']/sch:rule[1]/sch:assert[1]"
            relevant="instance('instance_model_root')[not( ex:A + ex:B = 100 )]"/>

清单 5 显示的绑定是为 Schematron 示例文档中的约束生成的。与约束绑定一样,这个绑定元素有一个 nodeset 属性,这个属性指定绑定将应用于 XML 数据实例中的哪个节点(在这个示例中是 Schematron 文档)。每个元素还包含一个 relevant 属性,它根据 Schematron 文档中对应的断言或报告的测试指定条件。只有在 relevant 属性值的计算结果为 true 的情况下,nodeset 属性值指定的节点才是相关的。如果一个数据节点是相关的,那么浏览器会显示与这个节点关联的任何 XForms 控件。如果节点不是相关的,那么通常会隐藏任何关联的控件。

因为表单可以将 Schematron 文档本身作为实例数据使用,所以可以将控件绑定到 Schematron 文档中的节点。对于这些节点,希望显示文本而不是提供输入数据的机会,所以 xforms:output 控件是自然的选择。

因为已经有了对 Schematron 消息应用相关性的数据绑定,所以可以使用 output 元素上的 bind 属性将每个控件与一个消息绑定在一起,见 清单 6


清单 6. 显示 Schematron 消息的控件
            <xforms:output bind="pattern_Our Only Pattern_rule_1_assert_1"
            model="model_root"/>

图 3 中的屏幕图显示这个表单在 Firefox 中的样子,其中值的和不等于 100。


图 3. Firefox 中的表单,其中的值不符合 Schematron 约束
Firefox 中的表单,其中的值不符合 Schematron 约束

清单 7 给出完整的表单源代码,它是用约束生成和消息生成选项生成的。注意两个实例:一个实例引用 XML 实例数据,另一个引用 Schematron 文档。


清单 7. 表单的源代码
            <?xml version="1.0" encoding="UTF-8"?>
            <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:xforms="http://www.w3.org/2002/xforms"
            xmlns:sch="http://www.ascc.net/xml/schematron"
            xmlns:ex="http://www.example.org">
            <head>
            <title>AB Form</title>
            <xforms:model id="model_root" schema="../data/Simple.xsd">
            <xforms:instance id="instance_model_root" src="../data/Simple.xml"/>
            <xforms:instance id="instance_model_root_schematron" src="../data/Simple.sch"/>
            <xforms:bind id="pattern_Our Only Pattern_rule_1_assert_1"
            nodeset="instance('instance_model_root_schematron')/
            sch:pattern[@name='Our Only Pattern']/sch:rule[1]/sch:assert[1]"
            relevant="instance('instance_model_root')[not( ex:A + ex:B = 100 )]"/>
            <xforms:bind nodeset="instance('instance_model_root')"
            constraint="instance('instance_model_root')[ex:A + ex:B = 100]"/>
            <xforms:submission id="submit_model_root" ref="instance('instance_model_root')"
            action="http://xformstest.org/cgi-bin/showinstance.sh"
            method="post"/>
            </xforms:model>
            </head>
            <body>
            <xforms:group>
            <xforms:label>AB Form</xforms:label>
            </xforms:group>
            <xforms:input ref="instance('instance_model_root')/ex:A" model="model_root">
            <xforms:label>A</xforms:label>
            </xforms:input>
            <xforms:input ref="instance('instance_model_root')/ex:B" model="model_root">
            <xforms:label>B</xforms:label>
            </xforms:input>
            <xforms:output bind="pattern_Our Only Pattern_rule_1_assert_1" model="model_root"/>
            <xforms:submit submission="submit_model_root">
            <xforms:label>Submit</xforms:label>
            </xforms:submit>
            </body>
            </html>

进一步的应用方向

在本文中,通过使用一个包含单一断言的简单 Schematron 文档,演示了 XML Forms Generator 的 Schematron 处理功能。XML Forms Generator 可以处理包含任意数量的规则声明的 Schematron 文档,还可以处理 Schematron report 元素和 Schematron assert 元素。

当然,您可能希望用约束在比较复杂的表单中实现其他效果。例如,当违反条件时,可能希望在信息性消息中提供违反条件的字段的链接。例如,Origo Standards Ltd. 开发的 Instance Validator 表单(见 参考资料)允许导航到发生问题的字段附近。但是注意,即使在简单的示例中,也可能不容易判断哪个字段是错的。例如,如果 A 和 B 的和不等于 100,那么不能只指出 A 错了或 B 错了。

生成的表单没有引用样式表,它包含的格式化特性也不多。XML Forms Generator 提供了本文没有讨论的许多选项,可以使用它们改进表单的外观和功能。XML Forms Generator 在 Eclipse 帮助系统中内置了丰富的文档。另外,它提供了许多示例,包括一个与本文示例相似的简单 Schematron 示例。还可以使用 Visual XForms Designer(也可以从 alphaWorks 获得,见 参考资料)根据自己的需要调整生成的表单。

利用这些免费工具,就可以轻松地构建功能完整的符合标准的表单。

原文转自:http://www.ltesting.net