etree/lxml/XSLT and dynamic stylesheet variables

Adam Tauno Williams awilliam at whitemice.org
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
> > <http://lxml.de/xpathxslt.html#stylesheet-parameters> 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:
> http://lxml.de/extensions.html

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>
  <document>
      <id>109</id>
      <category>OP</category>
      <title>Revolt Of The Masses</title>
      <author>Jose Ortega y Gasset</author>
      <published>1930</published>
      <language translator="anonymous">ES</language>
  </document>
  <document>
      <id>108</id>
      <category>P</category>
      <title>Meditations</title>
      <author>Marcus Aurelius</author>
      <language translator="Maxwell Staniforth">EL</language>
      <published>1930</published>
  </document>
  <document>
      <id>425</id>
      <category>OP</category>
      <title>The Communist Manifesto</title>
      <author>Karl Marx</author>
      <author>Friedrich Engels</author>
      <language translator="Samuel Moore">DE</language>
      <published>1914</published>
  </document>
  <document>
      <id>507</id>
      <category>POT</category>
      <title>The Cathedral & The Bazaar</title>
      <author>Eric S. Raymond</author>
      <published>199</published>
  </document>
</documents>'''

source = etree.fromstring(text)

style ='''<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:ext="847fe241-df88-45c6-b4a7">
   <xsl:output method="text"/>
   <xsl:template match="/documents/document">
     <xsl:value-of select="id"/>
     <xsl:text>,"</xsl:text>
     <xsl:value-of select="author"/>
     <xsl:text>","</xsl:text>
     <xsl:value-of select="ext:languagelookup(string(language))"/>
     <xsl:text>"</xsl:text>
   </xsl:template>
</xsl:stylesheet>'''

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

-- 
Adam Tauno Williams <http://www.whitemiceconsulting.com>
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: <http://mail.python.org/pipermail/python-list/attachments/20120121/71b9f63f/attachment-0001.sig>


More information about the Python-list mailing list