XQuery/使用 Schematron 进行验证
外观
< XQuery
您希望根据一组业务规则检查您的 XML 文档。这些规则可能比单次传递 XML 架构可以执行的规则更复杂。
Schematron 提供了与标准 Schema 不同的验证方法。它不是规定文档的正确形式,而是允许您定义可以根据需要应用的规则。您还可以使用 XPath 表达式在文档的一部分中指定引用文档其他部分的规则。当文档分阶段创建,并且需要在使用数据之前检查特定的业务规则时,这非常有用。
Schematron 也可以与传统的 XML 架构一起工作。您可以使用 XML 架构检查文档的整体结构和数据类型,并使用 Schematron 表达可以用 XPath 规则完成的规则。
Schematron 也是理想的,因为它允许规则设计者为规则指定确切的错误消息。XML 架构错误消息通常不容易被用户理解。
这是一个示例:在发送“学校预订”的确认电子邮件之前,预订必须包含学校/ID、教师的电子邮件地址和预订日期。日期必须在未来。
let $schema :=
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:title>School-booking Prior to Send-by-email</sch:title>
<sch:pattern id="Send-email-check">
<sch:rule context="school/id">
<sch:assert test=". ne ''">Missing School ID</sch:assert>
</sch:rule>
<sch:rule context="school/teacher-email">
<sch:assert test=". ne ''">Missing Teach-Email</sch:assert>
</sch:rule>
<sch:rule context="day">
<sch:assert test="date">Missing booking Date</sch:assert>
</sch:rule>
<sch:rule context="day/date">
<sch:assert test=". castable as xs:date and xs:date(.) gt current-date()">The Date must be in the future</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
要从 XQuery 应用此架构
xquery version "1.0"
let $send-email-validator :=
transform:transform(
$schema,
xs:anyURI("xmldb:///db/iso-schematron-xslt2/iso_svrl_for_xslt2.xsl"),() )
return transform:transform(
$the-data,
$send-email-validator,() )
以及结果(为了清楚起见而编辑)
<schematron-output title="School-booking Prior to Send-by-email" >
<failed-assert test=". ne ''" location="/school-booking[1]/school[1]/teacher-email[1]">
<text>Missing Teach-Email</svrl:text>
</failed-assert>
<failed-assert test=". castable as xs:date and xs:date(.) gt current-date()" location="/school-booking[1]/day[1]/date[1]">
<text>The Date must be in the future</svrl:text>
</failed-assert>
</schematron-output>
结果可用于突出显示错误并向用户显示消息。
我选择了 Schematron 验证的 XSLT 2.0 版本 - 所以 eXist-db 需要安装 Saxon 9。(...)
- 获取 iso-schematron-xslt2 并将(解压缩)内容上传到您的数据库。
- 在数据库中创建一个架构
- 编译并对您的数据运行架构
Jing 只支持 Schematron 1.5。Schematron 的一个更高级的版本是 ISO Schematron,Jing 无法运行它。要使其工作,您必须使用 XSLT“编译”您的 Schematron 规则。
以下是一个执行此编译的示例 XQuery 模块。
module namespace v="http://gspring.com.au/pekoe/validator";
declare variable $v:schematron-compiler := xs:anyURI("xmldb:///db/iso-schematron-xslt2/iso_svrl_for_xslt2.xsl");
(: Call like this: v:validate($xml, xs:anyURI("/db/path/to/schema.sch") ) :)
declare function v:validate($doc as node(), $schematron as xs:anyURI ) {
let $validator := local:get-compiled-validator($schematron)
return transform:transform(
$doc,
$validator,()
)
};
declare function local:get-compiled-validator($schematron-path as xs:anyURI) {
let $s-path := xs:string($schematron-path)
let $xsl-path := concat(substring-before($s-path,"."),".xsl")
return (: check that the compiled version is up-to-date :)
if (exists(doc($xsl-path)) and
xmldb:last-modified(util:collection-name($xsl-path), util:document-name($xsl-path)) gt
xmldb:last-modified(util:collection-name($s-path), util:document-name($s-path)))
then doc($xsl-path)
else local:compile-schematron($s-path,$xsl-path)
};
declare function local:compile-schematron($schematron-path, $xsl-path) {
let $compiled := transform:transform(
doc($schematron-path),
$v:schematron-compiler, ())
let $stored := xmldb:store(util:collection-name($schematron-path), $xsl-path, $compiled)
return doc($stored)
};
请注意,xslt 假设包含文件。