[lxml-dev] etree.XSLTApplyError: xsltValueOf: text copy failed (Custom XSLT function usage error)
Chas Emerick
cemerick at snowtide.com
Tue Nov 14 20:36:57 CET 2006
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 at snowtide.com
http://snowtide.com | +1 413.519.6365
More information about the lxml-dev
mailing list