Re: Last tango in Paris
Brought to you by:
bs_php,
nigelswinson
From: Nigel S. <nig...@us...> - 2002-07-12 01:48:19
|
(Really old thread alert...) > This is not the same thing. This is the last employee in each parent node if > male (or in my example the last of each tango which is in Paris, i.e. all > tangos in Paris). What I want is the last instance of all male employees, > i.e. > > //employee[@gender='m'][last()] > > should find a1010 and gender = 'f' should find a1006. > > Incidentally, if I try > > //employee[(@gender='m') and (last())] > > I get a different answer to your example. What is this doing? 'Position() = > last()' and 'last()' should surely be identical. //employee[(@gender='m') and (last())] And //employee[(@gender='m') and (position() = last())] Are NOT the same. Because of the "and" operator. what happens is that last() returns a number. The "and" takes two operands that need to be bools, so it has to convert the number from last() into a bool. If you think about it, last() always returns a non zero number, which always converts to TRUE. So for example I got confused by a test that I had that was //*[1 and last()] and was surprised to see that this returned different results to //*[1 and (position() = last())]. //*[1 and last()] actually matched EVERY node in the document. This is because: http://www.w3.org/TR/xpath#section-Node-Set-Functions "The last function returns a number equal to the context size from the expression evaluation context.The last function returns a number equal to the context size from the expression evaluation context." So last returns a non zero number, because context size >= 1. When you convert a non zero number to a bool, you get TRUE. So basically I was doing: //*[1 and TRUE]. So now it's not really surprising that it returned all the nodes. On the other hand, //*[1 and (position() = last())] must now evaluate the "position() = last()" as a bool, which only returns TRUE for the last node in the context. And hence //*[1 and (position() = last())] is the same as //*[(position() = last())] is the same as //*[last()], but is not the same as //*[1 and last()]. Seems a bit bizzare....but means we have less bugs than we'd thought :o) Nigel |