在 MarkLogic 中从 Schematron 调用外部 API 和库函数

Calling external API and library functions from Schematron in MarkLogic

通过为 ctsdohickey 声明适当的 <sch:ns/>,我可以调用 MarkLogic API 函数,例如编译后的 Schematron 中的 cts:*,如下所示( 很棒, 顺便说一下):

<sch:rule context="dohickey:thingummy">
    <sch:let name="this-id" value="dohickey:meta/dohickey:id/string()"/>
    <sch:let name="known-ids" value="cts:element-values(xs:QName('dohickey:id'))"/>
    <sch:report test="$this-id = $known-ids">Warning: This id is known, and that's a business error</sch:report>
</sch:rule>

(请忽略 $known-ids 变量将被优化以锁定现实生活中的单个值,而不是返回所有值---为了示例)

现在我想在我的 Schematron 中包含自定义 XQuery 模块,就像我在上面的示例中调用 cts:* 一样,并且在使用时我可以调用 XQuery 库函数原始 XSLT 和 MarkLogic XSLT/XQuery 集成通过定义,例如,xsl:stylesheet/@extension-element-prefixes 值,后跟适当的 <xdmp:import-module/>.

示例:我想执行以下操作:

<sch:rule context="dohickey:thingummy">
    <sch:let name="this-id" value="dohickey:meta/dohickey:id/string()"/>
    <sch:let name="is-flagged-for-revision" value="mycustommodule:is-flagged-for-revision($this-id)"/>
    <sch:report test="$is-flagged-for-revision">Warning: This id has been flagged for revision</sch:report>
</sch:rule>

问题:目前是否有办法让 MarkLogic 的 schematron:put 编译行为包括自定义 XQuery 模块导入,类似于 MarkLogic 的 XSLT <xdmp:import-module/> 支持?或者我应该只实现一个包装器来转换 schematron:put 编译结果以包含我需要的内容以便它在编译的 XSLT 中?

正如您自己提到的,您可以使用 <xdmp:import-module> 指令将 XQuery 库模块导入 MarkLogic 中的 XSLT 样式表。导入模块后,该模块中定义的任何函数都可用于该样式表。

可以将外来词汇合并到您的 Schematron 模式中。您可以使用它来将 xdmp:import-module 包含到已编译的模式中。但是,在编译Schematron 时需要将allow-foreign 参数设置为true。默认为 false.

在您的 Schematron 架构中,您首先需要使用 sch:ns 声明命名空间,以便识别前缀:

<sch:ns prefix="search" uri="http://marklogic.com/appservices/search"/>
<sch:ns prefix="xdmp" uri="http://marklogic.com/xdmp"/>

您添加外部标记,例如 xdmp:import-module 以导入 XQuery 库模块。将导入放在架构的根级别:

<xdmp:import-module namespace="http://marklogic.com/appservices/search" 
  href="/MarkLogic/appservices/search/search.xqy"/>

您可以直接使用之前定义的前缀在 Schematron 中使用导入的库函数:

<sch:rule context="test">
  <sch:let name="estimate" value="search:estimate(search:parse(@term))"/>
  <sch:assert test="$estimate gt 0" diagnostics="d1">At least one doc should be found</sch:assert>
</sch:rule>

只需确保在将 Schematron 模式编译成 XSLT 并使用 schematron:put() 将其加载到模块数据库时,将 allow-foreign 选项设置为 true(),如下所示:

xquery version "1.0-ml"; 
import module namespace schematron = "http://marklogic.com/xdmp/schematron" 
  at "/MarkLogic/schematron/schematron.xqy";

let $params := map:map()
  => map:with('allow-foreign', fn:true())
return
  schematron:put("/mySchema.sch", $params)