Schematron:测试字符串是否与可用 ID 列表中的 ID 匹配

Schematron: Test that a string matches an ID from a list of available IDs

我有一个 XML 文件,其中包含可能的问题答案列表以及正确答案。我想使用 schematron 验证可能的答案 ID 列表中是否存在正确的答案值(字符串)。

我正在将字符串值与列表 ID 进行比较,但结果不够。

XML:

<question>
    <div class="answer" id="i149">
        <div class="choice" id="i152">
            <div class="list" id="i154">
                <ol>
                    <li id="i155">Red</li>
                    <li id="i156">Blue</li>
                    <li id="i157">Green</li>
                    <li id="i158">Yellow</li>
                </ol>
            </div>
        </div>
    </div>
    <div class="response-processing" id="i159">
        <div class="condition" id="i161">
            <div class="correct" id="i162">
                <div class="response" id="i163">
                    <p>
                        <a class="answer-ref" href="#i152" id="i164">i1555</a>
                    </p>
                    <p>
                        <a class="answer-ref" href="#i152" id="i165">i156</a>
                    </p>
                    <p>
                        <a class="answer-ref" href="#i152" id="i166">i157</a>
                    </p>
                </div>
            </div>
        </div>
    </div>
</question>

Schematron 规则:

<pattern id="answerIDnotLocal">
        <let name="answer" value="ancestor::question/div[@class='answer']/div[@class='choice']/div[@class='list']/ol//li/@id"/>
        <rule context="a[@class='answer-ref']">
            <assert test=". = $answer">This <value-of select="."/> doesn't match an available answer id.</assert>
        </rule>
    </pattern>

但是,所有 3 个 <a class="answer-ref"> 都会触发错误,而只有第一个应该触发错误(值为 i1555 - 实际值应该是 i155)。

我认为您需要将 let 移到 rule 中,以便为 let:

提供正确的上下文
<pattern id="answerIDnotLocal">
        <rule context="a[@class='answer-ref']">
            <let name="answer" value="ancestor::question/div[@class='answer']/div[@class='choice']/div[@class='list']/ol//li/@id"/>
            <assert test=". = $answer">This <value-of select="."/> doesn't match an available answer id.</assert>
        </rule>
</pattern>

我找到了答案。需要使用量化表达式:

<pattern id="answerIDnotLocal">
        <rule context="question">
            <let name="answer" value="div[@class='response-processing']/div[@class = 'condition']/div[@class = 'correct']"/>
            <let name="choice" value="div[@class = 'answer']//div[@class = 'list']//li/@id"/>
            <assert test="every $a in $answer satisfies $a = $choice">This question doesn't match an available answer id.</assert>
        </rule>
</pattern>