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.
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.
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.
This is a sample xml piece:
<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:
//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.
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".
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:
//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
MyItemName
? How is that the first cell in the row? It sure doesn't look like it. – Wayne