The XPath axis, preceding-sibling, can be a bit confusing to use. It doesn't work the way one would expect at all. In fact, it is quite backward from what one would expect.
To me it made sense that if I wanted the sibling just before where I was currently at I would use an XPath like this:
preceding-sibling::NodeName[last()] |
That made sense to me... but it didn't work. After some digging around I discovered that preceding-sibling works in a reverse direction. If I were to diagram it out, using an 'X' to represent the current location, it would look like this:
preceding-sibling | current() | following-sibling |
last() | ... | 2 | 1 | X | 1 | 2 | ... | last() |
Thus, using last(), I would really end up with the first one in the list (as we humans think). So if I want access to the immediate preceding-sibling, I would instead use an XPath like this:
preceding-sibling::NodeName[1] |
This would correctly provide me with the immediate preceding-sibling (this technique is demonstrated in the InfoPathDev example form: Reordering Table Rows). I could increase the number used if I wanted to walk further back the chain.
So in essence, as you go forward (following-sibling) or backward (preceding-sibling), the number of steps you take is based off of where you currently are, with last() being the furthest possible away from where you are, in the direction you are going.
©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.