这是非常简单的事情(至少我猜),我只是没有得到线索。
我必须解析一个大型XML文档以获取一个特定节点,该节点由其子节点值之一标识。到目前为止这很容易。但是当我尝试从该节点向前解析时,通过使用谓词选择其祖先的前兄弟,我得到一个节点列表,从那里我必须再次向下走。
在Theorie中,这是一个表,有5列和2行(在下面的例子中)。我得到一个字段的id元素,需要找到行的第一个字段中给出的名称。第一个字段始终为“链接”类型,并且具有带文本的名称子节点 - 这是要获取的内容。
换句话说,我需要从具有<id>XXX_X</i>
的任何节点移动到具有xsi:type='Label'
控件和名称节点的下一个前兄弟单元格。从节点<id>MyItemId_1</>
我需要从节点<id>MyItemId_4</id>
获得第二个前面的兄弟节点,我需要获得第5个前面的兄弟节点。
这是一个示例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>
我确实得到了这个xpath必须得到的项目:
//cell[control[type='Link']]/control[type='Link' and selected='false' and id='MyItemId_3']/id
选择渲染表的单元格控件的id,即第二行的第4列。
从该节点开始,我尝试按照以下路径移动到该行中的第一个单元格:
../../preceding-sibling::cell[control[@xsi:type='Label' and name[node()]]]/control[name[node()]]/name
这给了我表格第一列的两个正确单元格。
<name>MyOtherItemName</name>
* * * * * * * * * *
<name>MyItemName</name>
现在它打破我的背部,因为我无法让它回到所选择的两个中的最后一个。
我试过了:
../../preceding-sibling::cell[control[@xsi:type='Label' and name[node()]]][1]/control[name[node()]]/name
这是一个前兄弟选择,其谓词与我搜索的兄弟姐妹的类型完全相同,但似乎我无法将该谓词与[1]选择器组合在一起。它不是选择所需的第一个前一个兄弟“MyItemName”,而是从前面的所有兄弟“MyOtherItemName”中选择第一个兄弟。
我需要帮助,希望有人在这里有一个线索,并能指出我正确的方向。
我设置的工作正是将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
答案 0 :(得分:13)
我不明白究竟是什么问题,但是兄弟姐妹从节点本身向文档的开头排序,即反过来比在文档中排序。要获取最近的前一个兄弟,请使用preceding-sibling[1]
来获取最远的兄弟(即文档顺序中的第一个),使用preceding-sibling[last()]
。
答案 1 :(得分:1)
阅读更新后,这不会起作用:
//cell[control/id="MyItemId_4"]/preceding-sibling::cell[control[@xsi:type='Label'] and not(control/name='')][1]
我对名称节点有点不确定:您是要测试名称节点中是否存在文本,还是仅存在名称节点本身?
答案 2 :(得分:1)
YourWebElement.FindElement(By.XPath(&#34;前同辈:: * [1]&#34));
这里1表示所选节点上方的兄弟节点,然后你可以进行递归,以便从下到上获得所有前面的兄弟节点。