Python, lxml, and xsl:include

Keeping this short because yes, dammit, I'm home sick.

I needed/wanted to do some XSL transformations with Python using an <xsl:include> 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() ...
<?xml version="1.0" encoding="iso-8859-1"?>
<div>
  <p>I'm from a.xsl.</p>
  <p>I'm from b.xsl.</p>
  <p>b-val c-val d-val</p>
</div>

Trying also_works() ...
<?xml version="1.0" encoding="iso-8859-1"?>
<div>
  <p>I'm from a.xsl.</p>
  <p>I'm from b.xsl.</p>
  <p>b-val c-val d-val</p>
</div>

Trying fails() ...

Traceback (most recent call last):
  File "C:\Users\nitaro\Dropbox\lxml_include\inc.py", line 44, in <module>
    print fails(myXML)
  File "C:\Users\nitaro\Dropbox\lxml_include\inc.py", line 23, in fails
    style = etree.XSLT(xsl_parsed)
  File "xslt.pxi", line 399, in lxml.etree.XSLT.__init__ (src/lxml/lxml.etree.c:118852)
  File "lxml.etree.pyx", line 280, in lxml.etree._ExceptionContext._raise_if_stored (src/lxml/lxml.etree.c:7959)
XSLTParseError: Cannot resolve URI string://__STRING__XSLT__/a.xsl

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>
--------------

Related Content:

Leave a Comment

Your email address will not be published. Required fields are marked *


*