查找符合条件的最近祖先/兄弟姐妹

时间:2011-12-14 14:54:49

标签: xml xpath

我的XML由容器节点组成,容器节点包含各种子节点,包括其他容器节点。示例XML看起来像......

<CONTAINER>
    <SEARCHFOR />
    <ITEM/>
    <ITEM/>
    <ITEM/>
    <ITEM/>
    <ITEM/>
    <CONTAINER>
        <SEARCHFOR />
        <ITEM/>
        <ITEM/>
        <CONTAINER>
            <SEARCHFOR />
            <ITEM id="1" />
            <ITEM/>
            <ITEM/>
            <CONTAINER>
                <ITEM id="2" />
            </CONTAINER>
        </CONTAINER>
    </CONTAINER>
</CONTAINER>

我想找到与id = 2的ITEM最近(范围内)的SEARCHFOR节点。 SEARCHFOR节点可以是ITEM的前兄弟节点,也可以是祖先CONTAINER节点的子节点。我有一个XPath表达式,可以找到范围内符合条件的所有SEARCHFOR节点,但我似乎无法让它只返回最接近的单个元素。

//ITEM[@id="2"]/ancestor::CONTAINER/SEARCHFOR

我正在使用Sketchpath进行测试,并将使用可以处理XPath 2.0的XML解析器在Delphi中实现它,以便语法也可以接受。我可以通过获取我的结果并使用Delphi获得感兴趣的代码来在代码中执行此操作,但是如果可能的话,我真的需要在XPath本身内完成我的实现。任何帮助表示赞赏。

谢谢, 迈克尔

2 个答案:

答案 0 :(得分:1)

也许这个XPath 2.0表达式回答了你的问题:

(//ITEM[@id='2']/(ancestor::CONTAINER/SEARCHFOR|preceding-sibling::SEARCHFOR))[last()]

它的工作原理是按文档顺序构建一系列元素,然后选择最后一个元素,给定您的描述,最近的(如果我说得对)。

答案 1 :(得分:1)

preceding轴以反向文档顺序搜索,因此选择第一个这样的前面元素按预期工作(只要我们可以假设SEARCHFOR元素本身不是目标的祖先{ {1}}):

ITEM

我们还可以假设(//ITEM[@id='2']/preceding::SEARCHFOR[parent::CONTAINER])[1] 元素总是在SEARCHFOR吗?如果是这样,那么我们不需要那种明确的检查,使其更短:

CONTAINER