blog.humaneguitarist.org

Python, lxml, and xsl:include

[Thu, 25 Oct 2012 16:27:08 +0000]
Keeping this short because yes, dammit, I'm home sick. I needed/wanted to do some XSL transformations with Python using an [http://www.w3schools.com/xsl/el_include.asp] statement. But I kept getting some errors along the lines of "lxml cannot' resolve uri string". So anyway after deciding I didn't want to read through all the crap on the lxml site about this, I fumbled my way through to what appears to work. It seems the include statements work fine when I DO NOT read() the XSL file before using it for a transformation. In the interest of really keeping it short like I said, here's some code and the results below. from lxml import etree def works(someXML): #don't even open() the XSL file ... xslt_tree = etree.parse(xslFile) transform = etree.XSLT(xslt_tree) result = transform(someXML) return result def also_works(someXML): #open() the XSL file, but don't read() it ... xsl_opened = open(xslFile, "r") xslt_tree = etree.parse(xsl_opened) transform = etree.XSLT(xslt_tree) result = transform(someXML) return result def fails(someXML): #open() and read() the XSL file ... xsl_opened = open(xslFile, "r") xsl_read = xsl_opened.read() xsl_parsed = etree.XML(xsl_read) transform = etree.XSLT(xsl_parsed) result = transform(someXML) return result ##### xslFile = "b.xsl" myXML = etree.XML('''\ <a> <b>b-val</b> <c>c-val</c> <d>d-val</d> </a>''') print "Trying works() ..." print works(myXML) print "Trying also_works() ..." print also_works(myXML) print "Trying fails() ..." print fails(myXML) Here's what the code spits out ... Trying works() ...<br/> <?xml version="1.0" encoding="iso-8859-1"?><br/> <div><br/> <p>I'm from a.xsl.</p><br/> <p>I'm from b.xsl.</p><br/> <p>b-val c-val d-val</p><br/> </div><br/> <br/> Trying also_works() ...<br/> <?xml version="1.0" encoding="iso-8859-1"?><br/> <div><br/> <p>I'm from a.xsl.</p><br/> <p>I'm from b.xsl.</p><br/> <p>b-val c-val d-val</p><br/> </div><br/> <br/> Trying fails() ...<br/> <br/> Traceback (most recent call last):<br/> File "C:\Users\nitaro\Dropbox\lxml_include\inc.py", line 44, in <module><br/> print fails(myXML)<br/> File "C:\Users\nitaro\Dropbox\lxml_include\inc.py", line 23, in fails<br/> style = etree.XSLT(xsl_parsed)<br/> File "xslt.pxi", line 399, in lxml.etree.XSLT.__init__ (src/lxml/lxml.etree.c:118852)<br/> File "lxml.etree.pyx", line 280, in lxml.etree._ExceptionContext._raise_if_stored (src/lxml/lxml.etree.c:7959)<br/> XSLTParseError: Cannot resolve URI string://__STRING__XSLT__/a.xsl<br/> Oh and here are the XSL files, "a.xsl" and "b.xsl" ... <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes"/> <xsl:template match="a"> <div> <p>I'm from a.xsl.</p> <xsl:call-template name="canUCme"> <xsl:with-param name="name" select="/" /> </xsl:call-template> </div> </xsl:template> </xsl:stylesheet> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:include href="a.xsl"/> <xsl:template name="canUCme"> <xsl:param name="name" /> <p>I'm from b.xsl.</p> <p><xsl:value-of select="normalize-space($name)" /></p> </xsl:template> </xsl:stylesheet>