【问题标题】:Find nearest ancestor/sibling that matches criteria查找符合条件的最近祖先/兄弟姐妹
【发布时间】:2011-12-14 14:54:48
【问题描述】:

我有一个由容器节点组成的 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 中进行测试,并将在 Delphi 中使用可以处理 XPath 2.0 的 XML 解析器来实现它,这样语法也是可以接受的。我可以在代码中通过获取我的结果并使用 Delphi 来获得感兴趣的结果,但如果可能的话,我真的需要在 XPath 本身内完成此操作以实现我的实现。任何帮助表示赞赏。

谢谢, 迈克尔

【问题讨论】:

    标签: xml xpath


    【解决方案1】:

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

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

    它的工作原理是按文档顺序构建一系列元素,然后选择最后一个,根据您的描述,它是最接近的(如果我没记错的话)。

    【讨论】:

    • 最优秀。谢谢。对于我的简单示例,这是完美的,应该适合我的 20 多行 xpath,我真的很好。啊!我的脑子全是,但现在被炸了。
    【解决方案2】:

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

    (//ITEM[@id='2']/preceding::SEARCHFOR[parent::CONTAINER])[1]
    

    我们是否也可以假设SEARCHFOR 元素总是在CONTAINER 中?如果是这样,那么我们就不需要那个显式检查,让它更短:

    (//ITEM[@id='2']/preceding::SEARCHFOR)[1]
    

    【讨论】:

    • 感谢您的建议。这适用于示例,我会尽量记住这一点以供将来参考,但在我的实际应用程序中,我的 xpath 和 XML 一样复杂得多,并且上面的第一个建议需要更少的字符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 2022-08-19
    相关资源
    最近更新 更多