You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

lxml.isoschematron无法编译测试表达式,求可行解决办法

问题描述

我正尝试使用RNG schema,通过lxml结合RelaxNG和Schematron规则验证XML。这种方式在TEI这类复杂XML场景中很常见,但找到低依赖的可靠验证器却出奇困难。我反复遇到lxml.etree.XSLTParseError错误,涉事测试表达式在其他环境中可正常运行,想知道可行的解决办法。

以下是最小复现示例:

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)

完整错误信息:
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'

错误原因

lxml的isoschematron模块默认基于XSLT 1.0实现Schematron验证,而表达式中的gt是XPath 2.0及以上版本才支持的比较运算符。XSLT 1.0对应的是XPath 1.0,不识别gt,需要用标准的>运算符替代。

解决办法

将断言表达式中的gt替换为>,修改后的代码如下:

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())) > 0">A test rule.</assert>
    </rule>
  </pattern>
</schema>
"""
)

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

修改后,表达式就能被lxml的XSLT 1.0引擎正确编译,验证流程可正常运行。


内容的提问来源于stack exchange,提问作者Andrew Dunning

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:02:19