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

如何在Python中用Schematron和XSD验证CII D16B电子发票XML?

解决Python中EN16931 CII D16B电子发票的Schematron验证问题

针对多命名空间、复杂嵌套规则的EN16931 CII D16B电子发票Schematron验证,推荐以下两种可行的Python实现方案:

方案一:使用lxml结合Schematron转XSLT(免费开源)

Schematron可转换为XSLT执行验证,lxml对XSLT 1.0支持完善,能处理多命名空间场景,步骤如下:

  1. 准备依赖文件

    • 获取EN16931核心Schematron文件(EN16931-CII-validation.sch)
    • 获取标准Schematron转XSLT骨架文件(iso_schematron_skeleton.xsl,可从Schematron官方资源获取)
  2. 代码实现

from lxml import etree

def validate_cii_invoice(schematron_path, xslt_skeleton_path, invoice_xml_path):
    # 加载Schematron和转换骨架
    schematron_doc = etree.parse(schematron_path)
    xslt_skeleton = etree.XSLT(etree.parse(xslt_skeleton_path))
    
    # 将Schematron转换为验证用XSLT
    validation_xslt = xslt_skeleton(schematron_doc)
    
    # 加载待验证的发票XML
    invoice_doc = etree.parse(invoice_xml_path)
    
    # 执行验证
    validation_result = etree.XSLT(validation_xslt)(invoice_doc)
    
    # 解析验证结果
    errors = []
    ns = {"svrl": "http://purl.oclc.org/dsdl/svrl"}
    for error in validation_result.xpath("//svrl:failed-assert", namespaces=ns):
        error_msg = error.xpath("./svrl:text/text()", namespaces=ns)[0]
        context = error.xpath("./@location", namespaces=ns)[0]
        errors.append(f"验证失败 [{context}]: {error_msg}")
    
    if errors:
        print("验证不通过:")
        for err in errors:
            print(f"- {err}")
        return False
    else:
        print("验证通过")
        return True

# 调用示例
validate_cii_invoice(
    schematron_path="./EN16931-CII-validation.sch",
    xslt_skeleton_path="./iso_schematron_skeleton.xsl",
    invoice_xml_path="./generated_invoice.xml"
)
  1. 关键注意事项
    • 确保所有依赖文件路径正确且文件完整
    • 转换后的XSLT会继承原Schematron中的命名空间定义,无需手动绑定
    • 若出现命名空间相关错误,检查原Schematron是否完整包含CII的四个命名空间声明

方案二:使用SaxonC(商业级支持,需授权)

如果对验证性能和复杂规则兼容性要求更高,可选择SaxonC的Python绑定。它原生支持Schematron 1.5,无需手动转换XSLT,对嵌套规则和多命名空间处理更高效。

  1. 安装依赖
    获取授权版本后,安装Python绑定:

    pip install saxonc
    
  2. 代码实现

import saxonc

def validate_with_saxonc(schematron_path, invoice_xml_path):
    with saxonc.PySaxonProcessor(license=False) as proc:
        # 创建Schematron验证器
        schema_validator = proc.new_schema_validator()
        schema_validator.set_schematron_source(XdmNode=proc.parse_xml(xml_file_name=schematron_path))
        
        # 加载待验证XML
        invoice_node = proc.parse_xml(xml_file_name=invoice_xml_path)
        
        # 执行验证
        validation_report = schema_validator.validate(node=invoice_node)
        
        # 解析结果
        if validation_report.is_valid():
            print("验证通过")
            return True
        else:
            print("验证不通过:")
            for error in validation_report.get_error_list():
                print(f"- 行{error.line_number}: {error.message}")
            return False

# 调用示例
validate_with_saxonc(
    schematron_path="./EN16931-CII-validation.sch",
    invoice_xml_path="./generated_invoice.xml"
)
  1. 关键注意事项
    • SaxonC免费版本功能有限,完整支持EN16931规则需商业授权
    • 授权版本提供更详细的错误上下文,便于定位问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:49:53