跳轉到內容

XQuery/使用 Schematron 進行驗證

來自華夏公益教科書,開放的書籍,面向開放的世界

您希望根據一組業務規則檢查您的 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>

結果可用於突出顯示錯誤並向用戶顯示訊息。

在 eXist-db 中設定

[編輯 | 編輯原始碼]

我選擇了 Schematron 驗證的 XSLT 2.0 版本 - 所以 eXist-db 需要安裝 Saxon 9。(...)

  1. 獲取 iso-schematron-xslt2 並將(解壓縮)內容上傳到您的資料庫。
  2. 在資料庫中建立一個架構
  3. 編譯並對您的資料執行架構

用於 ISO Schematron 的 XQuery 模組

[編輯 | 編輯原始碼]

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

華夏公益教科書