xml xpath 获取特定前兄弟的最后一个
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9167000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
xpath get last of specific preceding-sibling
提问by Oliver Friedrich
Here's something really simple (at least I guess), I just do not get the clue.
这是一些非常简单的事情(至少我猜),我只是不明白。
I have to parse a large XML document to get a specific node, identified by one of its subnode values. Thats easy so far. But when I try to parse onward from that node relatively upward, selecting the preceding-siblings of its ancestor by using a predicate I get a list of nodes, from that on I have to walk downward again.
我必须解析一个大型 XML 文档以获取特定节点,该节点由其子节点值之一标识。到目前为止,这很容易。但是,当我尝试从该节点相对向上解析时,使用谓词选择其祖先的前兄弟时,我会得到一个节点列表,然后我必须再次向下走。
In Theorie, that is a table, with 5 columns and two rows (in the shown example below). I get just the id element of one field, and need to find the name given in the first field of the row. The first field is always of type 'Link' and has a name subnode with text - which is the thing to get.
在 Theorie 中,这是一个表,有 5 列和两行(在下面显示的示例中)。我只得到一个字段的 id 元素,并且需要找到行的第一个字段中给出的名称。第一个字段始终是“链接”类型,并且有一个带有文本的名称子节点 - 这就是要获得的东西。
In other words, I need to move from any node with an <id>XXX_X</i>to the next preceding-sibling cell with a control of xsi:type='Label'and a name node. From the node <id>MyItemId_1</>I need to get the second preceding-sibling, from the node <id>MyItemId_4</id>I need to get the 5th preceding-sibling.
换句话说,我需要从具有 的任何节点移动<id>XXX_X</i>到具有控制xsi:type='Label'和名称节点的下一个前同级单元。从节点<id>MyItemId_1</>我需要获得第二个前兄弟,从节点<id>MyItemId_4</id>我需要获得第 5 个前兄弟。
This is a sample xml piece:
这是一个示例 xml 片段:
<cell>
<control xsi:type="Label">
<id>1234</id>
<name>MyOtherItemName</name>
<message/>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Label">
<id>MyOtherItemId_0</id>
<name/>
<message/>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Label">
<id>MyOtherItemId_1</id>
<name/>
<message/>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Button">
<id>MyOtherItemId_2</id>
<name>552</name>
<message/>
<type>Link</type>
<selected>false</selected>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Button">
<id>MyOtherItemId_3</id>
<name>432</name>
<message/>
<type>Link</type>
<selected>false</selected>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Button">
<id>MyOtherItemId_4</id>
<name>33</name>
<message/>
<type>Link</type>
<selected>false</selected>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Label">
<id>1234</id>
<name>MyItemName</name>
<message/>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Label">
<id>MyItemId_0</id>
<name/>
<message/>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Label">
<id>MyItemId_1</id>
<name/>
<message/>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Button">
<id>MyItemId_2</id>
<name>552</name>
<message/>
<type>Link</type>
<selected>false</selected>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Button">
<id>MyItemId_3</id>
<name>432</name>
<message/>
<type>Link</type>
<selected>false</selected>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
<cell>
<control xsi:type="Button">
<id>MyItemId_4</id>
<name>33</name>
<message/>
<type>Link</type>
<selected>false</selected>
</control>
<selected>false</selected>
<style>Odd</style>
</cell>
I do get the item i have to get with this xpath:
我确实得到了我必须用这个 xpath 得到的东西:
//cell[control[type='Link']]/control[type='Link' and selected='false' and id='MyItemId_3']/id
That selects the id of the control of the cell, namely the 4th column in the second row, of the rendered table.
这将选择单元格控件的 id,即呈现表格的第二行中的第 4 列。
From that node on I try moving to the first cell in the row by following this path:
从该节点开始,我尝试按照以下路径移动到行中的第一个单元格:
../../preceding-sibling::cell[control[@xsi:type='Label' and name[node()]]]/control[name[node()]]/name
That gives me the two correct cells of the first column of the table.
这给了我表格第一列的两个正确单元格。
<name>MyOtherItemName</name>
* * * * * * * * * *
<name>MyItemName</name>
Now it breaks my back since I can't get it to just give me back the last one of the two selected.
现在它打破了我的背,因为我无法让它只给我选择的两个中的最后一个。
I tried this:
我试过这个:
../../preceding-sibling::cell[control[@xsi:type='Label' and name[node()]]][1]/control[name[node()]]/name
which is a preceding-sibling selection with a predicate to exactly the sort of siblings I search for, but it seems I can not combine that predicate with a [1] selector. Instead of selecting the desired first preceding sibling "MyItemName" it selects the first sibling from all preceding ones "MyOtherItemName".
这是一个前置的兄弟选择,其中的谓词恰好是我搜索的兄弟姐妹的类型,但似乎我无法将该谓词与 [1] 选择器结合起来。它不是选择所需的第一个前面的兄弟“MyItemName”,而是从所有前面的“MyOtherItemName”中选择第一个兄弟。
I need help, hope someone here has a clue and can pinpoint me in the right direction.
我需要帮助,希望这里有人有线索,可以指出我正确的方向。
Exactly what I set up to get this work is copying the xml into http://www.bit-101.com/xpath/and working with the concatenated xpathes on it to simulate what the software should do:
我为完成这项工作所做的设置是将 xml 复制到http://www.bit-101.com/xpath/并使用连接的 xpathes 来模拟软件应该做什么:
//cell[control[type='Link']]/control[type='Link' and selected='false' and id='MyItemId_3']/id/../../preceding-sibling::cell[control[@xsi:type='Label' and name[node()]]]/control[name[node()]]/name
回答by choroba
I do not understand what the problem exactly is, but preceding-siblings are sorted from the node itself towards the beginning of the document, i.e. the other way round than in the document. To get the nearest preceding sibling, use preceding-sibling[1], to get the farthest one (i.e. the first one in the document order), use preceding-sibling[last()].
我不明白问题到底是什么,但前兄弟从节点本身到文档的开头排序,即与文档中的相反。要获取最近的前面同级,请使用preceding-sibling[1],要获取最远的(即文档顺序中的第一个),请使用preceding-sibling[last()]。
回答by forty-two
After reading your update, wouldn't this work:
阅读您的更新后,这行不通:
//cell[control/id="MyItemId_4"]/preceding-sibling::cell[control[@xsi:type='Label'] and not(control/name='')][1]
I'm a bit unsure about the name node: do you want to test for existence of text in the the name node or just existence of the name node itself?
我对名称节点有点不确定:您是要测试名称节点中是否存在文本,还是仅测试名称节点本身是否存在?
回答by Prathyusha Dwibhashi
YourWebElement.FindElement(By.XPath("preceding-sibling::*[1]"));
YourWebElement.FindElement(By.XPath("preceding-sibling::*[1]"));
Here 1 indicates just the sibling above the selected node and then you can do recursion in order to get all the preceding siblings from bottom to top.
这里 1 仅表示所选节点上方的同级,然后您可以进行递归以从下到上获得所有前面的同级。

