Цикл for-each в схематроне

Я самоучка, поэтому заранее извиняюсь за все свои ошибки.

Мой xml содержит 50 элементов testwithstate, каждый из которых включает атрибут ID. Мне не удалось запустить цикл for-each, и я попытался создать как можно более простой тест, чтобы найти свои ошибки, но безуспешно. Мой код ниже. Заранее спасибо за любую помощь.

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://purl.oclc.org/dsdl/schematron" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" queryBinding="xslt2" xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
 <ns uri="http://www.w3.org/1999/xlink" prefix="xlink"/>
 <ns prefix="xs" uri="http://www.w3.org/2001/XMLSchema"/>
 
 <pattern>
  <rule context="testwithstate">
   <xsl:for-each select="/@id">
    <report test="1=1">It ran.</report>
   </xsl:for-each>
  </rule>
 </pattern>

</schema>

person Tom    schedule 24.12.2020    source источник
comment
Как вы думаете, зачем вам нужен цикл xsl:for-each внутри вашей схемы Schematron? И какую реализацию Schematron вы используете, какой результат вы хотите получить с приведенным выше примером и какую ошибку или результат вы получаете вместо этого?   -  person Martin Honnen    schedule 24.12.2020
comment
Во-первых, спасибо, что нашли время ответить. Я только пытаюсь научиться. Насколько я понимаю, должен работать xsl:for-each. Чтобы убедиться, что это так, я ожидаю вывод It run. для каждого экземпляра testwithstate, так же, как когда я помещаю ‹report вне цикла. Как бы то ни было, я не получаю никаких ошибок и никакого вывода. Как будто цикл не выполняется. Я не знаю, какую реализацию использует мой работодатель, и я понимаю, что реализация может не позволить запустить цикл. Если вы можете сказать мне, что в моем коде нет ничего плохого, я сделаю вывод, что это реализация.   -  person Tom    schedule 25.12.2020
comment
Я бы попробовал чистый Schematron, например. <rule context="testwithstate/@id"><report test="true()">It ran.</report></rule>. Хотя предполагается, что использование queryBinding="xslt2" позволит вам использовать объявление XSLT 2, такое как xsl:function или xsl:key, внутри вашего Schematron перед любыми правилами, я думаю, я не уверен, что общее использование инструкций XSLT, таких как xsl:for-each, где-то разрешено или указано и имеет хорошо- определенное значение, если вы не пытаетесь использовать какую-то конкретную реализацию или расширение на основе XSLT.   -  person Martin Honnen    schedule 25.12.2020
comment
И в целом как с Schematron, так и с XSLT, как только вы устанавливаете контекст, такой как элемент testwithstate, внутри вы используете относительные выражения XPath, такие как @id, для выбора/доступа к атрибуту id элемента контекста. Использование /@id попытается выбрать атрибут id узла документа, узлы документа даже не имеют атрибутов, они есть только у узлов элементов.   -  person Martin Honnen    schedule 25.12.2020
comment
Благодарю вас! Все ваши предложения входят в число тех, которые я пробовал, прежде чем обратиться на этот форум, и результаты точно такие, как вы описываете. Цикл просто не работает, когда я его реализую. Я подозреваю, что моя проблема - это моя попытка использовать его в общем, как вы указываете. Я благодарен за вашу помощь.   -  person Tom    schedule 26.12.2020
comment
До сих пор не ясно, почему вы думаете, что вам нужно добавить какой-то XSLT в ваш Schematron, если вы используете <rule context="testwithstate/@id"><report test="true()">It ran.</report></rule>, каждый testwithstate/@id атрибут должен дать вам отчет It ran. о проверке.   -  person Martin Honnen    schedule 26.12.2020
comment
У меня нет особой необходимости использовать XSLT в моем Schematron. Я видел много примеров for-each внутри XSL-функций в Schematron, и я просто пытался узнать, можно ли использовать for-each в общем случае. Я ценю ваше продолжение и вашу помощь.   -  person Tom    schedule 27.12.2020


Ответы (1)


Я много пишу в schematron, и когда мне нужен расширенный xsl-код для запуска, я разделяю его для работы, таким образом, вы можете использовать оба в полную силу. Я привожу вам пример. Этот код может не иметь для вас особого смысла, это фрагмент, но он показывает вам способ смешивания schematron и xslt:

<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<sch:pattern id="TPOD0470" is-a="abstractPatternWarning">
        <sch:param name="CONDITION" value="string-length(foo:foutenTPOD_0470(.)[1]) = 0"/>
</sch:pattern>
    
    <xsl:function name="foo:foutenTPOD_0470">
        <xsl:param name="context" as="node()"/>
        <xsl:for-each select="$context/../tekst:Titel">
            <xsl:if test="$context/@eId=@eId and not(starts-with(tekst:Kop/tekst:Nummer, concat($context/../tekst:Kop/tekst:Nummer, '.')))">
                <xsl:value-of select="@eId"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:function>
</sch:schema>
person Bert Verhees    schedule 01.01.2021