[lxml-dev] Context of custom XPath functions

Stefan Behnel stefan_ml at behnel.de
Fri Aug 24 09:41:21 CEST 2007


Hi,

Frederik Elwert wrote:
> Am Donnerstag, den 23.08.2007, 21:59 +0200 schrieb Stefan Behnel:
>> There is an older API in lxml.etree that supports per-call extension
>> definitions. It's not very well documented, but you can pass a list of
>>
>>   [ {(ns, name):function} ]
>>
>> dicts as "extensions" kw arg into the constructor of XPath evaluators. It
>> should work with any 1.x version of lxml.etree.

it actually /is/ documented, sorry:

http://codespeak.net/lxml/extensions.html#evaluator-local-extensions

(It's been a while since I wrote these docs, so I keep forgetting what's in
there - and what isn't :)


> I just played a bit with this, and I came up with a custom element class
> that provides these functions, so they can access the context
> information. In addition to the xpath method, they provide a new
> "xfpath" method:
> 
> class XFormsElement(ET.ElementBase):
> 
>     def instance(self, _, idref):
>         tree = self.getroottree()
>         namespaces = {'xf': 'http://www.w3.org/2002/xforms'}
>         result = tree.xpath('//xf:instance[@id="%s"]' % idref, namespaces)
>         return(result)
>         
>     def xfpath(self, expr):
>         extensions = {(None, 'instance'): self.instance}
>         return self.xpath(expr, extensions=extensions)
> 
> myelement.xfpath("instance('scales')")
> 
> I'm not sure if this is really the best solution, but it works. 

Well, it's maybe not the most efficient thing ever, as it requires re-parsing
the XPath expression each time. But it works with most lxml versions and
solves your problem, which is worth more than peek performance IMHO. I also
like how simple it is, BTW.

I'll also commit the context stuff for lxml 2.0, I think that really is a
helpful addition.

Stefan



More information about the lxml-dev mailing list