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>