let's fighting love: using Jinja templates with XSL

It's Friday and I should be out with a drink in my hand.

Instead, I have pinkeye.

Dammit.

Anyway, I've been finishing up a script at work that uses XSL and I have a way to pass some variables with into the XSL code to augment what can be done. I've mentioned this a little before here although now I use a prettier template-like syntax as such:

<xsl:variable name="baseURL" select="'{{$BASE_URI}}'" />
<xsl:variable name="URL_params" select="'{{$CURRENT_PARAMS}}'" />

But today I was wondering about eventually (i.e. not now) using Jinja2 with XSL, i.e. use its templating within XSL code. I really like what little I've done using Jinja templates with Google App Engine (Python).

So anyway, here's some test code. It seems very promising.

I'm sure it's been done before, but I'm just a little bored.

Hell, I named the XSL transformer function "gobot", m'kay?

def jinjafy(xsl):
  from jinja2 import Template
  template = Template(xsl)
  result = template.render(name="John Doe")
  return result

def gobot(xml, xsl):
  from lxml import etree
  xml_tree = etree.XML(xml)
  xslt_tree = etree.XML(xsl)
  transform = etree.XSLT(xslt_tree)
  result = transform(xml_tree)
  return result
 
#####
myXML = ('''\
<a>
  <b>Hello </b>
</a>''')

myXSL = jinjafy('''\
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text" version="1.0" /> 
  <xsl:template match="a">
    <xsl:value-of select="b" />
    <xsl:value-of select="'{{ name }}'" />
    <xsl:text>!</xsl:text>
  </xsl:template>
</xsl:stylesheet>''')

print gobot(myXML, myXSL) #yields: "Hello John Doe!"

Here's a better example …

def jinjafy(xsl):
  from jinja2 import Template
  template = Template(xsl)
  result = template.render(template_values)
  return result

def gobot(xml, xsl):
  from lxml import etree
  xml_tree = etree.XML(xml)
  xslt_tree = etree.XML(xsl)
  transform = etree.XSLT(xslt_tree)
  result = transform(xml_tree)
  return result
 
#####
names = ["John Doe", "Jane Doe"]
template_values = {"names": names}

myXML = ('''\
<a>
  <b>Hello </b>
</a>''')

myXSL = jinjafy('''\
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text" version="1.0" />
  <xsl:template match="a">
    {% for name in names %}
      <xsl:value-of select="b" />
      <xsl:value-of select="'{{ name }}'" />
      <xsl:text>! </xsl:text>
    {% endfor %}
  </xsl:template>
</xsl:stylesheet>''')

print gobot(myXML, myXSL) #yields: "Hello John Doe! Hello Jane Doe!"

And while we're on the subject …

    Leave a Comment

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

    *