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 假設包含檔案。