Вызов внешнего API и библиотечных функций из Schematron в MarkLogic

При правильном объявлении <sch:ns/> для cts и dohickey я могу вызывать функции API MarkLogic, такие как cts:*, из скомпилированного Schematron следующим образом (что, кстати, круто):

<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 будет оптимизирована для блокировки одного значения в реальной жизни, вместо того, чтобы возвращать их все --- ради примера)

Теперь я хотел бы включить пользовательские модули XQuery в свой Schematron так же, как я могу вызвать 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, аналогично поддержке <xdmp:import-module/> XSLT от MarkLogic? Или я должен просто реализовать оболочку, которая преобразует скомпилированный результат schematron:put, чтобы включить то, что мне нужно, в скомпилированный XSLT?


person Markus Flatscher    schedule 24.11.2019    source источник
comment
Я подозреваю, что официальные XSLT Schematron используются под прикрытием, поэтому я не думаю, что он будет поддерживать импорт. Тем не менее, должно быть достаточно легко исправить XSLT, чтобы добавить импорт. Вы можете попробовать сделать это с помощью xdmp:node-insert-child ..   -  person grtjn    schedule 25.11.2019
comment
Оказывается, на самом деле существует удобный способ компиляции OOTB - см. Принятый ответ @ mads-hansen ниже.   -  person Markus Flatscher    schedule 26.11.2019


Ответы (1)


Как вы сами упомянули, вы можете использовать инструкцию <xdmp:import-module> для импорта библиотеки XQuery. модуль в таблицу стилей XSLT в MarkLogic. После импортирования модуля любые функции, определенные в этом модуле, становятся доступными для этой таблицы стилей.

В схему Schematron можно включить иностранные словари. Вы можете использовать это, чтобы включить xdmp:import-module в скомпилированную схему. Тем не менее, вам необходимо установить _ 3_ в true при компиляции Schematron. По умолчанию 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() < / a>, вы устанавливаете для параметра 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)
person Mads Hansen    schedule 26.11.2019
comment
Фантастика! Спасибо, Мэдс --- Я пропустил параметр allow-foreign при компиляции. Вызов пользовательских библиотечных функций из Schematron работает как шарм. (Вплоть до 9.0-7, кстати.) - person Markus Flatscher; 26.11.2019
comment
Ответ на этот вопрос не совсем ясен, но я предполагаю, что этот импорт должен быть добавлен к скомпилированным таблицам стилей схемы в базе данных модулей, как я упоминал выше. Но, может быть, @ mads-hansen подтвердит? - person grtjn; 26.11.2019
comment
Нет необходимости в ручном обходе или постобработке. Добавьте <xdmp:import> непосредственно в файл Schematron * .sch, и он будет скопирован в скомпилированный XSLT (если для флага allow-foreign установлено значение true) - person Mads Hansen; 26.11.2019