Something really simple here (at least I think), I just don't understand.
I need to parse a large XML document to get a specific node defined by one of its subnode values. So far it has been easy. But when I try to analyze farther from this node relatively up, choosing the predecessor siblings of my ancestor using the predicate, I get a list of nodes from which I have to go down again.
In theory, this is a table with 5 columns and two rows (in the example below). I get only the id element from one field and should find the name specified in the first field of the row. The first field is always of type “Link” and has the name of a subset with text - this is what you need to get.
In other words, I need to go from any node with <id>XXX_X</i>
to the next cell of the previous cathedral using the xsi:type='Label'
control xsi:type='Label'
and the name node. From node <id>MyItemId_1</>
I need to get the second previous-sibling, from node <id>MyItemId_4</id>
I need to get the 5th previous-sibling.
This is an xml sample:
<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 get the element I should get with this xpath:
//cell[control[type='Link']]/control[type='Link' and selected='false' and id='MyItemId_3']/id
This selects the identifier of the cell control, namely the 4th column in the second row of the displayed table.
From this node on, I am trying to go to the first cell in the row, following this path:
../../preceding-sibling::cell[control[@xsi:type='Label' and name[node()]]]/control[name[node()]]/name
This gives me two correct cells in the first column of the table.
<name>MyOtherItemName</name> * * * * * * * * * * <name>MyItemName</name>
Now he has broken my back, since I can’t get him to simply return the last of the two selected to me.
I tried this:
../../preceding-sibling::cell[control[@xsi:type='Label' and name[node()]]][1]/control[name[node()]]/name
which is the choice of the previous sibling with the predicate of exactly the kind of siblings that I am looking for, but it seems I can not combine this predicate with the selector [1]. Instead of selecting the desired first previous sibling “MyItemName”, he selects the first brother from all previous “MyOtherItemName”.
I need help, I hope that someone has a key and can identify me in the right direction.
Exactly what I created for this job is copying the xml to http://www.bit-101.com/xpath/ and working with the concatenated xpathes on it to mimic 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