Venus and lxml

Dethe Elza delza at livingcode.org
Sat Jul 7 02:51:17 EST 2007


Hi folks,

I was trying to install Venus on dreamhost and ran into a couple of  
problem: While dreamhost supports Python up to 2.4 (and I have my own  
versions of 2.4 and 2.5 installed), it did not have the python  
bindings for libxslt or xsltproc installed.  Since I'm installing it  
to create a personal aggregator for my new Nokia N800, not being able  
to run the atom templates was a problem.

Since this is a hosted account, I cannot simply apt-get the files  
needed, but since I have my own python installed already I can  
easy_install to my heart's content.  Unfortunately, the libxslt  
python wrapper doesn't work with setuptools.

I could compile and install libxml, libxml-dev, libxslt, and libsxlt- 
dev, but that would be a PITA. On the other hand, lxml (which  
includes libxml and libxslt, but with an ElementTree-based API) is  
installable via easy_install.  So I modified planet/shell/xslt.py to  
use lxml instead of the libxslt python wrapper.  Below is the single  
function I changed.

Thanks for the great work on Planet, Venus, etc.  It was quite easy  
to get in and make the changes I needed.

--Dethe

def run(script, doc, output_file=None, options={}):
     """ process an XSLT stylesheet """
     '''
     script is a filename string
     doc is an xml string
     output_file is a filename string
     '''
     try:
         # if available, use the lxml python interface to libxslt
         from lxml import etree
         from StringIO import StringIO
         dom = etree.parse(StringIO(doc))
         docfile = None
     except:
         # otherwise, use the command line interface
         dom = None

     # do it
     result = None
     if dom:
         styledoc = etree.parse(script)
         style = etree.XSLT(styledoc)
         for key in options.keys():
             options[key] = quote(options[key], apos="\xe2\x80\x99")
         output = style(dom) # how to pass in options?
         if output_file:
             out_f = open(output_file, 'w')
             out_f.write(etree.tostring(output))
         else:
             result = etree.tostring(output)
     elif output_file:
         import warnings
         if hasattr(warnings, 'simplefilter'):
             warnings.simplefilter('ignore', RuntimeWarning)
         docfile = os.tmpnam()
         file = open(docfile,'w')
         file.write(doc)
         file.close()

         cmdopts = []
         for key,value in options.items():
            cmdopts += ['--stringparam', key, quote(value, apos=r"\'")]

         os.system('xsltproc %s %s %s > %s' %
             (' '.join(cmdopts), script, docfile, output_file))
         os.unlink(docfile)
     else:
         import sys
         from subprocess import Popen, PIPE

         options = sum([['--stringparam', key, value]
             for key,value in options.items()], [])

         proc = Popen(['xsltproc'] + options + [script, '-'],
             stdin=PIPE, stdout=PIPE, stderr=PIPE)

         result, stderr = proc.communicate(doc)
         if stderr:
             import planet
             planet.logger.error(stderr)

     return result




More information about the devel mailing list