XPath:从子节点获取父节点


157

我需要为子节点获取父节点 title 50

目前我只使用

//*[title="50"]

我怎么能得到它的父母?结果应为store节点。


<?xml version="1.0" encoding="utf-8"?>
<d:data xmlns:d="defiant-namespace" d:mi="23">
    <store d:mi="22">
        <book price="12.99" d:price="Number" d:mi="4">
            <title d:constr="String" d:mi="1">Sword of Honour</title>
            <category d:constr="String" d:mi="2">fiction</category>
            <author d:constr="String" d:mi="3">Evelyn Waugh</author>
        </book>
        <book price="8.99" d:price="Number" d:mi="9">
            <title d:constr="String" d:mi="5">Moby Dick</title>
            <category d:constr="String" d:mi="6">fiction</category>
            <author d:constr="String" d:mi="7">Herman Melville</author>
            <isbn d:constr="String" d:mi="8">0-553-21311-3</isbn>
        </book>
        <book price="8.95" d:price="Number" d:mi="13">
            <title d:constr="String" d:mi="10">50</title>
            <category d:constr="String" d:mi="11">reference</category>
            <author d:constr="String" d:mi="12">Nigel Rees</author>
        </book>
        <book price="22.99" d:price="Number" d:mi="18">
            <title d:constr="String" d:mi="14">The Lord of the Rings</title>
            <category d:constr="String" d:mi="15">fiction</category>
            <author d:constr="String" d:mi="16">J. R. R. Tolkien</author>
            <isbn d:constr="String" d:mi="17">0-395-19395-8</isbn>
        </book>
        <bicycle price="19.95" d:price="Number" d:mi="21">
            <brand d:constr="String" d:mi="19">Cannondale</brand>
            <color d:constr="String" d:mi="20">red</color>
        </bicycle>
    </store>
</d:data>

Answers:


295

使用带有父节点名称的parent

//*[title="50"]/parent::store

如果XPath是父节点,则它将仅选择该父节点store

但您也可以使用其中之一

//*[title="50"]/parent::*
//*[title="50"]/..

这些xpath将选择任何父节点。因此,如果文档发生更改,即使它不是您期望的节点,您也将始终选择一个节点。

编辑

在给定的示例中,父母是自行车,父母是商店,会发生什么?

它会上升吗?

不,如果它是match的节点的父节点,则仅选择商店//*[title="50"]

如果不是,是否有一种在这种情况下上升的方法,如果没有这样的父级,则返回None?

是的,您可以使用ancestor

//*[title="50"]/ancestor::store

这将选择//*[title="50"]存储的节点匹配的所有祖先。例如

<data xmlns:d="defiant-namespace" d:mi="23">
    <store mi="1">
        <store mi="22">
            <book price="8.95" d:price="Number" d:mi="13">
                <title d:constr="String" d:mi="10">50</title>
                <category d:constr="String" d:mi="11">reference</category>
                <author d:constr="String" d:mi="12">Nigel Rees</author>
            </book>
        </store>
    </store>
</data>

XPath选择结果


7
你也可以使用parent::*缩写语法..(例如://*[title="50"]/..)或嵌套谓词(例如://*[*[title="50"]]
丹尼尔·海利


3
还是parent::node()对应于快捷方式..,我认为更好。实际上parent::*仅限于轴的主要节点类型,在大多数情况下这不是问题。
Ludovic Kuty 2015年

3
如果您使用try .xpath('..')xpath('parent::node()')
briankip '16

“此XPath仅在存储时选择父节点。” -在给定的示例中,当父母是父母bicycle但父母是父母时会发生store什么?它会上升吗?如果不是,是否有一种方法可以在这种情况下上升并在None没有此类父项的情况下返回?
马丁·托马

31

作为替代方案,您可以使用ancestor

//*[title="50"]/ancestor::store

它比parent它强大得多,因为它甚至可以得到祖父母或曾曾祖父母


20
它不是“更强大”。只是不同而已。因此,轴的选择取决于使用情况。
Ludovic Kuty

11

您也可以在表达式末尾使用两个点。请参阅以下示例:

//*[title="50"]/..

2

新的,经过改进的答案,可以回答一个古老而又常见的问题...

我怎么能得到它的父母?结果应为store节点。

使用谓词而不是parent::or ancestor::

此处的大多数答案都选择title,然后遍历到目标的父级或祖先(store)元素。一种更简单直接的方法是首先直接选择父元素或祖先元素,而无需遍历到a parent::ancestor::轴:

//*[book/title = "50"]

中间元素的名称应不同:

//*[*/title = "50"]

或者,在名称和深度上:

//*[.//title = "50"]

这不能回答问题。作者不一定事先知道父母的名字。
Kenn Sebesta

1
@KennSebesta:我已更新答案以解决您的问题。如果您的异议得到解决,请删除您的否决票,或者如果您认为答案有问题,请告诉我们。谢谢。
kjhughes

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.