How to debug lxml.etree.XSLTParseError: Invalid expression error
Question:
I’m trying to find out why lxml cannot parse an XSL document which consists of a “root” document with various xml:include
s. I get an error:
Traceback (most recent call last):
File "s.py", line 10, in <module>
xslt = ET.XSLT(ET.parse(d))
File "xslt.pxi", line 409, in lxml.etree.XSLT.__init__ (src/lxml/lxml.etree.c:151978)
lxml.etree.XSLTParseError: Invalid expression
That tells me where in the lxml source the error is, but is there a way to get more through lxml about where in the xsl the error is, or should I be using a different method? I’m trying to provide a service that accepts XSL documents, so I don’t have access to an XML editor to debug manually. What I would like to do though is give feedback about why a transformation didn’t succeed.
Answers:
Looking at the exception’s properties, I see that it has an error_log, but for an xpath error (for example) the log only includes information about where within the xpath the error is, so it’s not especially helpful. For the use-case I describe, having arbitrary users submitting XSLT, there’s not a push-button approach. Instead, it would be probably be easiest to use a combination of schema validation and custom logic to find out where the error is and why it’s an error for the purpose of reporting back to the user.
Error in package lxmlxslt.pxi
can indicate fault with xslt tempalte, processing errors can be extracted from property transform.error_log
. An example:
import lxml
import lxml.etree
xmlPath = '/path/data.xml'
xslPath = '/path/template.xlst'
xslRoot = lxml.etree.parse(xslPath)
transform = lxml.etree.XSLT(xslRoot)
xmlDoc = lxml.etree.parse(xmlPath)
try:
resultDoc = transform(xmlDoc)
except:
pass
for entry in transform.error_log:
print('file', entry.filename
, entry.line, entry.column, entry.message
, entry.domain_name, entry.domain)
, entry.type_name, entry.type)
, entry.level_name, entry.level)
Source: errors-and-messages (lxml.de)
I’m trying to find out why lxml cannot parse an XSL document which consists of a “root” document with various xml:include
s. I get an error:
Traceback (most recent call last):
File "s.py", line 10, in <module>
xslt = ET.XSLT(ET.parse(d))
File "xslt.pxi", line 409, in lxml.etree.XSLT.__init__ (src/lxml/lxml.etree.c:151978)
lxml.etree.XSLTParseError: Invalid expression
That tells me where in the lxml source the error is, but is there a way to get more through lxml about where in the xsl the error is, or should I be using a different method? I’m trying to provide a service that accepts XSL documents, so I don’t have access to an XML editor to debug manually. What I would like to do though is give feedback about why a transformation didn’t succeed.
Looking at the exception’s properties, I see that it has an error_log, but for an xpath error (for example) the log only includes information about where within the xpath the error is, so it’s not especially helpful. For the use-case I describe, having arbitrary users submitting XSLT, there’s not a push-button approach. Instead, it would be probably be easiest to use a combination of schema validation and custom logic to find out where the error is and why it’s an error for the purpose of reporting back to the user.
Error in package lxmlxslt.pxi
can indicate fault with xslt tempalte, processing errors can be extracted from property transform.error_log
. An example:
import lxml
import lxml.etree
xmlPath = '/path/data.xml'
xslPath = '/path/template.xlst'
xslRoot = lxml.etree.parse(xslPath)
transform = lxml.etree.XSLT(xslRoot)
xmlDoc = lxml.etree.parse(xmlPath)
try:
resultDoc = transform(xmlDoc)
except:
pass
for entry in transform.error_log:
print('file', entry.filename
, entry.line, entry.column, entry.message
, entry.domain_name, entry.domain)
, entry.type_name, entry.type)
, entry.level_name, entry.level)
Source: errors-and-messages (lxml.de)