[lxml-dev] Some XPath questions...
Stefan Behnel
stefan_ml at behnel.de
Tue Jul 3 08:54:03 CEST 2007
Ian Bicking wrote:
>>>>>>> >>> xpath('E:empty')
>>>>>>> e[count(./children::*) = 0 and string(.) = '']
>>>>>>> But maybe I don't understand how count() works; this isn't a
>>>>>>> valid XPath expression.
>>>>>> You want "child" not "children". Using normalize-space(.) instead of
>>>>>> string(.) will exclude whitespace. This does assume you are ignoring
>>>>>> comments and PIs; I believe that's the behavior you want.
>>>>> Cool, that seems to work right.
>>>> What about "e[not(*) and not(normalize-space())]" ?
>>> Yes, that works too.
>>
>> That's the 'implicit conversion' I was talking about. You're relying
>> on 0 and the empty string being false. It's a standard idiom, and
>> pythonic, but I'm not sure you want to use it in automatically
>> generated code, since it means you can't generalize the code from "has
>> 0 children" to "has n children".
>
> In this case it's a fixed expression used for e:empty, and nothing else,
> so it seems fine. And possibly makes the resulting expression a bit
> easier to recognize from its CSS roots.
It's also likely faster. I don't think libxml2 optimises the comparisons, so
looking for "not(*)" can stop false after the first node, while
"count(./child::*) = 0" needs to count all children and then sees that, oh,
the number is bigger than 0.
Stefan
More information about the lxml-dev
mailing list