首页 > 解决方案 > XPath:查找祖先元素中的下一次出现

问题描述

我试图在 sec-type='reading' 的一部分中找到下一个实例。

XML 示例:

<?xml version="1.0" encoding="US-ASCII"?>
<book>
    <sec sec-type="reading">
        <title>Section 1</title>
        <p>Sample <bold>Bold</bold>Text <fn><label>1</label></fn> Some more text</p>
        <!-- more variations of stuff at various levels -->
        <sec>
            <title>Section 1.1</title>
            <p>Another paragraph with a footnote <fn><label>2</label></fn></p>
        </sec>
        <sec>
            <title>Section 1.2</title>
            <p>Another paragraph with a footnote <fn><label>3</label></fn></p>
        </sec>
    </sec>

    <sec sec-type="reading">
        <title>Section 2</title>
        <p>Sample <bold>Bold</bold>Text <fn><label>6</label></fn> Some more text</p>
        <!-- more variations of stuff at various levels -->
        <sec>
            <title>Section 2.1</title>
            <p>Another paragraph with a footnote <fn><label>8</label></fn></p>
        </sec>
        <sec>
            <title>Section 2.2</title>
            <p>Another paragraph with a footnote <fn><label>9</label></fn></p>
        </sec>
    </sec>
</book>

目的是查看 FN 标签是否在一个部分内按顺序排列。我用 6-9 对第二部分进行了编号,以便更容易查看它是否有效。

这就是我要的:

Footnote 1 [Next: 2]
Footnote 2 [Next: 3]
Footnote 3 [Next: ]
Footnote 6 [Next: 8]
Footnote 8 [Next: 9]
Footnote 9 [Next: ]

最终目标是返回警告Footnote 6 [Next: 8]

这是我到目前为止的schematron。这给了我:

Footnote 1 [Next: 2]
Footnote 2 [Next: 3]
**Footnote 3 [Next: 6]**
Footnote 6 [Next: 8]
Footnote 8 [Next: 9]
Footnote 9 [Next: ]

它找到脚注的下一个实例。但是,我不希望它跨越这些部分 - 这Footnote 3 [Next: 6]是错误的。

<?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"  >

  <!--check if footnotes are sequential within a reading -->
  <pattern id="footnote-sequential"> 
    <rule context="fn"> 
        <let name="next" value="following::fn[1]/label/text()"/>

        <assert test="number(label/text()) > 40">
        Footnote <value-of select='label'/> 
          [Next: <value-of select="$next"/>]
      </assert>
    </rule> 
  </pattern>
</schema>

注意:number(label/text()) > 40在断言中是为了捕捉此刻的一切。它最终会成为类似的东西number(current)+1 != number(next)

我得到的最接近的是ancestor::sec[@sec-type='reading']//following::fn[1]/label/text()- 但这会丢失“下一个”并给我这样奇怪的结果:

    Footnote 1 [Next: 1236]
    Footnote 2 [Next: 1236]
    Footnote 3 [Next: 1236]
    Footnote 6 [Next: 689]
    Footnote 8 [Next: 689]
    Footnote 9 [Next: 689]

标签: xpathschematron

解决方案


你需要intersect.

[编辑]

设置$nextfn元素而不是标签文本:

<let name="next" value="following::fn[1]"/>

[/编辑]

转到您当前的部分并记下该部分的所有脚注:

<let name="sect-fns" value="ancestor::sec[@sec-type='reading']//fn" />

$next在和上进行相交$sect-fns

<let name="next" value="$next intersect $sect-fns" />

检查是否$next为空或其标签为number(./label) + 1

<assert test="not($next) or number(./label) + 1 = number($next/label)">

推荐阅读