Как мы можем добавить информацию xpath в вывод сообщения об ошибке schematron - PullRequest
0 голосов
/ 27 августа 2018

Я использую API Schematron в MarkLogic для проверки 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)

Может ли кто-нибудь помочь мне получить информацию о XPath узла контекста вместе с выводом сообщения об ошибке schematron.

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Этот конкретный модуль Schematron довольно ограничен и не предоставляет способ вернуть XPath для узла контекста из отчета или неудачного утверждения.

Стандартный вывод Schematron SVRL включает XPath для элементов, которые запускают неудачные утверждения или отчеты.

Норм Уолш опубликовал модуль ML-Schematron , который объединяет компиляцию схемы Schematron в XSLT с использованием таблиц стилей Schematron и последующее выполнение скомпилированного XSLT для генерации отчета SVRL.

Вы можете настроить свой модуль так, чтобы он использовался вместо него (после установки и *1000* стандартных файлов Schematron XSLT в вашей базе данных модулей):

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, который включает XPath в атрибуте местоположения /*[local-name()='book']/*[local-name()='chapter']:

<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>
0 голосов
/ 27 августа 2018

Вот код того, о чем я думаю, вы просите.

Если вы хотите xpath элемента, вы можете использовать xdmp:path. чтобы получить xpath всего документа, вам нужно просто пройтись по дереву, что и делает рекурсивная функция local:getXpathDeep. Вы можете изменить формат вывода с string-join, который я использовал, мне стало проще читать. Я создал вывод в формате XML, чтобы поместить в него как результаты схемы, так и 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...