pythonxmllxmlschematrontei

lxml.isoschematron cannot compile test expression


I am attempting to use an RNG schema to validate XML against RelaxNG and Schematron rules with lxml. This is a common arrangement for more complex forms of XML, such as TEI, but it is surprisingly difficult to find a reliable validator with minimal dependencies. I keep receiving lxml.etree.XSLTParseError errors on test expressions that work elsewhere. Is there a way to work around this?

This is a minimal example, based on the lxml documentation:

from io import StringIO

from lxml import etree, isoschematron

f = StringIO(
    """\
<schema xmlns="http://purl.oclc.org/dsdl/schematron" >
  <pattern id="origDate">
    <title>Original date rule</title>
    <rule context="Total">
      <assert test="@calendar and (@when or @notBefore or @notAfter or @from or @to) and string-length(normalize-space(string())) gt 0">A test rule.</assert>
    </rule>
  </pattern>
</schema>
"""
)

sct_doc = etree.parse(f)
schematron = isoschematron.Schematron(sct_doc)

The full error message is lxml.etree.XSLTParseError: xsl:when : could not compile test expression '@calendar and (@when or @notBefore or @notAfter or @from or @to) and string-length(normalize-space(string())) gt 0'.


Solution

  • Use > instead of gt.

    gt is in XPath 2.0 and later. 'lxml' is presumably working with XSLT 1.0 and XPath 1.0, which don't support gt.

    Compare https://www.w3.org/TR/1999/REC-xpath-19991116/#NT-RelationalExpr and https://www.w3.org/TR/xpath20/#doc-xpath-ComparisonExpr