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

在MarkLogic中从Schematron调用外部API和库函数,marklogic,marklogic-9,schematron,Marklogic,Marklogic 9,Schematron,通过为cts和dohickey声明适当的函数,我可以从编译的Schematron中调用MarkLogic API函数,例如cts:*如下所示,顺便说一句,这非常棒: <sch:rule context="dohickey:thingummy"> <sch:let name="this-id" value="dohickey:meta/dohickey:id/string()"/> <sch:let name="known-ids" value="ct

通过为cts和dohickey声明适当的函数,我可以从编译的Schematron中调用MarkLogic API函数,例如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>

问:目前是否有一种方法可以让MarkLogic的schematron:put编译行为包括自定义XQuery模块导入,类似于MarkLogic的XSLT支持?或者我应该实现一个包装器来转换schematron:put compiled result以包含我需要的内容,从而将其包含在已编译的XSLT中吗?

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

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

在Schematron模式中,首先需要使用sch:ns声明名称空间,以便识别前缀:

<sch:ns prefix="search" uri="http://marklogic.com/appservices/search"/>
<sch:ns prefix="xdmp" uri="http://marklogic.com/xdmp"/>
您可以使用前面定义的前缀直接在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>

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

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

在Schematron模式中,首先需要使用sch:ns声明名称空间,以便识别前缀:

<sch:ns prefix="search" uri="http://marklogic.com/appservices/search"/>
<sch:ns prefix="xdmp" uri="http://marklogic.com/xdmp"/>
您可以使用前面定义的前缀直接在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是在暗中使用的,所以我认为它不会支持导入。不过,修补XSLT以添加导入应该很容易。您可以尝试使用xdmp:node insert child进行编译。事实证明,实际上有一种OOTB方便的编译方法——请参阅下面@mads hansen接受的答案。我怀疑官方的Schematron XSLT是在暗中使用的,因此我认为它不支持导入。不过,修补XSLT以添加导入应该很容易。您可以尝试使用xdmp:node insert child进行编译。事实证明,实际上有一种OOTB方便的编译方法——请参见下面@mads hansen接受的答案。太棒了!谢谢,Mads——我错过了编译时的allow foreign param。从Schematron调用自定义库函数非常有效。一路回到9.0-7,顺便说一句。关于这一点,答案并不完全明确,但我想这些导入必须附加到模块数据库中已编译的schematron样式表中,就像我上面提到的那样。但也许@mads hansen可以确认?不需要手动解决方法或后期处理。将直接添加到Schematron*.sch文件中,只要将allow foreign标志设置为trueFantastic,它就会被复制到已编译的XSLT中!谢谢,Mads——我错过了编译时的allow foreign param。从Schematron调用自定义库函数非常有效。一路回到9.0-7,顺便说一句。关于这一点,答案并不完全明确,但我想这些导入必须附加到模块数据库中已编译的schematron样式表中,就像我上面提到的那样。但也许@mads hansen可以确认?不需要手动解决方法或后期处理。直接在Schematron*.sch文件中添加,只要allow foreign标志设置为true,它就会被复制到已编译的XSLT中
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)