etree/lxml/XSLT and dynamic stylesheet variables

Adam Tauno Williams awilliam at
Sat Jan 21 13:07:21 EST 2012

On Sat, 2012-01-21 at 05:56 +0100, Stefan Behnel wrote:
> Adam Tauno Williams, 20.01.2012 21:38:
> > I'm using etree to perform XSLT transforms, such as -
> > from lxml import etree
> > source = etree.parse(self.rfile)
> > xslt = etree.fromstring(self._xslt)
> > transform = etree.XSLT(xslt)
> > result = transform(source)
> > according to the docs at
> > <> I can pass a
> > dictionary of parameters to transform, such as -
> > result = transform(doc_root, **{'non-python-identifier': '5'})
> > Can I pass a dictionary-like object?  That doesn't seem to be working.
> Yes it does, Python copies it into a plain dict at call time.

Ah, I wondered if that was happening.  In which case is supresses all
the magic of my dict subclass.

> > I need to perform dynamic lookup of variables for the stylesheet.
> Different story.
> > I've subclassed dictionary and overloaded [], get, has_key, and in to
> > perform the required lookups; these work in testing. But passing the
> > object to transform doesn't work
> You should make the lookup explicit in your XSLT code using an XPath
> function. See here:

Perfect thanks;  this provides everything I need.  

A stupid test case / example for anyone interested:

from lxml import etree

class MyExt:
    def __init__(self, languages):
	self._languages = languages

    def languagelookup(self, _, arg):
        language = self._languages.get(arg)
        if not language:
            return 'undefined'
        return language

extensions = etree.Extension( MyExt(languages={ 'ES': 'Spanish',
                                                'EL': 'Greek', 
                                                'DE': 'German',
                                                'EN': 'English' } ),
                              ( 'languagelookup', ), 
                              ns='847fe241-df88-45c6-b4a7' )

text = '''<documents>
      <title>Revolt Of The Masses</title>
      <author>Jose Ortega y Gasset</author>
      <language translator="anonymous">ES</language>
      <author>Marcus Aurelius</author>
      <language translator="Maxwell Staniforth">EL</language>
      <title>The Communist Manifesto</title>
      <author>Karl Marx</author>
      <author>Friedrich Engels</author>
      <language translator="Samuel Moore">DE</language>
      <title>The Cathedral & The Bazaar</title>
      <author>Eric S. Raymond</author>

source = etree.fromstring(text)

style ='''<xsl:stylesheet version="1.0"
   <xsl:output method="text"/>
   <xsl:template match="/documents/document">
     <xsl:value-of select="id"/>
     <xsl:value-of select="author"/>
     <xsl:value-of select="ext:languagelookup(string(language))"/>

xslt = etree.XSLT(etree.XML(style), extensions=extensions)
print xslt(source)

Adam Tauno Williams <>
System Administrator, OpenGroupware Developer, LPI / CNA
Fingerprint 8C08 209A FBE3 C41A DD2F A270 2D17 8FA4 D95E D383
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <>

More information about the Python-list mailing list