[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