Xquery 如何在schematron错误消息输出中添加xpath信息

Xquery 如何在schematron错误消息输出中添加xpath信息,xquery,xslt-2.0,marklogic,schematron,Xquery,Xslt 2.0,Marklogic,Schematron,我正在MarkLogic中使用SchematronAPI来验证XML文档。下面是供参考的代码片段 xquery version "1.0-ml"; import module namespace sch = "http://marklogic.com/validate" at "/MarkLogic/appservices/utils/validate.xqy"; import module namespace transform = "http://marklogic.com/trans

我正在MarkLogic中使用SchematronAPI来验证XML文档。下面是供参考的代码片段

xquery version "1.0-ml";

import module namespace sch = "http://marklogic.com/validate" at 
"/MarkLogic/appservices/utils/validate.xqy";

import module namespace transform = "http://marklogic.com/transform" at "/MarkLogic/appservices/utils/transform.xqy";

declare namespace xsl = "http://www.w3.org/1999/XSL/not-Transform";

declare namespace iso = "http://purl.oclc.org/dsdl/schematron";


let $document :=
      document{
        <book xmlns="http://docbook.org/ns/docbook">
              <title>Some Title</title>
              <chapter>
              <para>...</para>
              </chapter>
        </book>
      }

let $schema := 
    <s:schema xmlns:s="http://purl.oclc.org/dsdl/schematron"
              xmlns:db="http://docbook.org/ns/docbook">
       <s:ns prefix="db" uri="http://docbook.org/ns/docbook"/>
       <s:pattern name="Glossary 'firstterm' type constraint">
          <s:rule context="db:chapter">
             <s:assert test="db:title">Chapter should contain title</s:assert>
          </s:rule>
       </s:pattern>
     </s:schema>
return
 sch:schematron($document, $schema)
xquery版本“1.0-ml”;
导入模块命名空间sch=”http://marklogic.com/validate“在
“/MarkLogic/appservices/utils/validate.xqy”;
导入模块命名空间转换=”http://marklogic.com/transform“at”/MarkLogic/appservices/utils/transform.xqy”;
声明命名空间xsl=”http://www.w3.org/1999/XSL/not-Transform";
声明命名空间iso=”http://purl.oclc.org/dsdl/schematron";
让$document:=
文件{
一些头衔
...
}
让$schema:=
章节应包含标题
返回
sch:schematron($document,$schema)

有谁能帮我获取上下文节点的XPath信息以及schematron错误消息输出。

以下是我认为您需要的代码

如果需要项目的xpath,可以使用
xdmp:path
。为了获得整个文档的xpath,您只需遍历树,递归函数
local:getXpathDeep
就是这么做的。您可以更改我使用的
字符串联接
的输出格式,这使我更容易阅读。我创建了一个XML输出,将schematron结果和XPath放入其中,但是如果愿意,您可以返回一个序列或将其放入映射中

xquery version "1.0-ml";

import module namespace sch = "http://marklogic.com/validate" at 
"/MarkLogic/appservices/utils/validate.xqy";

import module namespace transform = "http://marklogic.com/transform" at "/MarkLogic/appservices/utils/transform.xqy";

declare namespace xsl = "http://www.w3.org/1999/XSL/not-Transform";

declare namespace iso = "http://purl.oclc.org/dsdl/schematron";

declare function local:getXpathDeep($node){
  (
    xdmp:path($node), 
    if (fn:exists($node/*)) then (
      local:getXpathDeep($node/*)
    ) else ()
  )
};

let $document :=
      document{
        <book xmlns="http://docbook.org/ns/docbook">
              <title>Some Title</title>
              <chapter>
              <para>...</para>
              </chapter>
        </book>
      }

let $schema := 
    <s:schema xmlns:s="http://purl.oclc.org/dsdl/schematron"
              xmlns:db="http://docbook.org/ns/docbook">
       <s:ns prefix="db" uri="http://docbook.org/ns/docbook"/>
       <s:pattern name="Glossary 'firstterm' type constraint">
          <s:rule context="db:chapter">
             <s:assert test="db:title">Chapter should contain title</s:assert>
          </s:rule>
       </s:pattern>
     </s:schema>
return
  <result>
    <contextNodeXpath>{fn:string-join(local:getXpathDeep($document), " 
    " )}</contextNodeXpath>
    <schematronOutPut>{sch:schematron($document, $schema)}</schematronOutPut>
  </result>
xquery版本“1.0-ml”;
导入模块命名空间sch=”http://marklogic.com/validate“在
“/MarkLogic/appservices/utils/validate.xqy”;
导入模块命名空间转换=”http://marklogic.com/transform“at”/MarkLogic/appservices/utils/transform.xqy”;
声明命名空间xsl=”http://www.w3.org/1999/XSL/not-Transform";
声明命名空间iso=”http://purl.oclc.org/dsdl/schematron";
声明函数本地:getXpathDeep($node){
(
xdmp:path($node),
如果(fn:存在($node/*)),则(
本地:getXpathDeep($node/*)
)else()
)
};
让$document:=
文件{
一些头衔
...
}
让$schema:=
章节应包含标题
返回
{fn:string连接(本地:getXpathDeep($document),”
" )}
{sch:schematron($document,$schema)}

特定的Schematron模块相当有限,无法从报告或失败的断言返回上下文节点的XPath

标准Schematron SVRL输出确实包含触发失败断言或报告的项的XPath

Norm Walsh已经发布了一个示例,该示例使用Schematron样式表将Schematron模式的编译打包到XSLT中,并随后执行编译后的XSLT以生成SVRL报告

您可以调整模块以使用它(在模块数据库中安装模块和后):


您可以尝试基于XSLT的schematron验证,而不是使用ML schematron验证API,通过该验证可以轻松获得XPATH。看看SVRL
xquery version "1.0-ml";
declare namespace svrl="http://purl.oclc.org/dsdl/svrl";
import module namespace sch="http://marklogic.com/schematron" at "/schematron.xqy";

let $document :=
      document{
        <book xmlns="http://docbook.org/ns/docbook">
              <title>Some Title</title>
              <chapter>
              <para>...</para>
              </chapter>
        </book>
      }

let $schema := 
    <s:schema xmlns:s="http://purl.oclc.org/dsdl/schematron"
              xmlns:db="http://docbook.org/ns/docbook">
       <s:ns prefix="db" uri="http://docbook.org/ns/docbook"/>
       <s:pattern name="Glossary 'firstterm' type constraint">
          <s:rule context="db:chapter">
             <s:assert test="db:title">Chapter should contain title</s:assert>
          </s:rule>
       </s:pattern>
     </s:schema>

return
  sch:validate-document($document, $schema)
<svrl:schematron-output title="" schemaVersion="" xmlns:schold="http://www.ascc.net/xml/schematron" 
xmlns:iso="http://purl.oclc.org/dsdl/schematron" xmlns:xhtml="http://www.w3.org/1999/xhtml" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:db="http://docbook.org/ns/docbook" xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias" 
xmlns:svrl="http://purl.oclc.org/dsdl/svrl">
  <!---->
  <svrl:ns-prefix-in-attribute-values uri="http://docbook.org/ns/docbook" prefix="db"/>
  <svrl:active-pattern document=""/>
  <svrl:fired-rule context="db:chapter"/>
  <svrl:failed-assert test="db:title" location="/*[local-name()='book']/*[local-name()='chapter']">
    <svrl:text>Chapter should contain title</svrl:text>
  </svrl:failed-assert>
</svrl:schematron-output>