[lxml-dev] etree.XSLTApplyError: xsltValueOf: text copy failed (Custom XSLT function usage error)
One of the key features of lxml from our perspective is the stated availability of custom function bindings within xslt. However, we've run into some difficulty in implementing them. Here's a concise example. First, we set up our custom function, nothing special:
from lxml import etree as ET ns = ET.FunctionNamespace(None) ns['testfunction'] = lambda dummy, *args: 'function args: %s' % str(args)
Next, we put together a really simple xml document -- and we can see that calling this custom function within direct XPath calls works just fine:
doc = ET.parse(StringIO('<p style="margin-top:5px">Normal <b>BOLD</b> text</p>')) doc.xpath('testfunction(5, 4, 3, 2, 1, "some string")') "function args: (5.0, 4.0, 3.0, 2.0, 1.0, 'some string')" doc.xpath('testfunction(//b)') 'function args: ([<Element b at 11d2058>],)' doc.xpath('testfunction(//*)') 'function args: ([<Element p at 11d24e0>, <Element b at 11d2058>],)'
Now, we come to our trouble: calling the custom function from within an XSLT stylesheet:
ET.XSLT(ET.parse(StringIO(''' <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml"/> <xsl:template match="*"> <x> <xsl:value-of select="testfunction(.)"/> </x> </xsl:template> </xsl:stylesheet> ''')))(doc) Traceback (most recent call last): File "<stdin>", line 1, in ? File "xslt.pxi", line 445, in etree.XSLT.__call__ etree.XSLTApplyError: xsltValueOf: text copy failed
I found a mention of this error being related to libxslt not accepting the results of xpath expressions as arguments into custom functions (<http://www.stylusstudio.com/xsllist/200604/ post40310.html>). However, calling the custom function from within the stylesheet using numeric literals also fails:
ET.XSLT(ET.parse(StringIO(''' <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml"/> <xsl:template match="*"> <elt> <xsl:value-of select="testfunction(5, 6)"/> </elt> </xsl:template> </xsl:stylesheet>''')))(doc) Traceback (most recent call last): File "<stdin>", line 1, in ? File "xslt.pxi", line 445, in etree.XSLT.__call__ etree.XSLTApplyError: xsltValueOf: text copy failed
---------------- Any thoughts? I have a hunch that we're just missing something simple (perhaps in setting up the function namespace and the function binding, but it seems like we're following the examples in the docs pretty closely). FYI, this is in python 2.4, with lxml 1.1.2. Thanks much, Chas Emerick Founder, Snowtide Informatics Systems Enterprise-class PDF content extraction cemerick@snowtide.com http://snowtide.com | +1 413.519.6365
Hi, Chas Emerick wrote:
One of the key features of lxml from our perspective is the stated availability of custom function bindings within xslt. However, we've run into some difficulty in implementing them. Here's a concise example.
First, we set up our custom function, nothing special:
from lxml import etree as ET ns = ET.FunctionNamespace(None) ns['testfunction'] = lambda dummy, *args: 'function args: %s' % str(args)
You should generally avoid using empty namespaces for functions. It's not a big deal to use a local fake namespace here, but it prevents you from running into a number of difficult to track down problems. Could you retry with an explicit namespace and report back if that also fails? Stefan
participants (2)
-
Chas Emerick -
Stefan Behnel