电子发票业务规则验证
HPDFEInvoiceValidator 将 Factur-X 或 ZUGFeRD 容器验证与显式选择、带版本的业务规则集和国家规则集相结合
完整审查规则执行
库为 MINIMUM、BASIC WL、BASIC、EN 16931 和 EXTENDED 提供匹配的 `.sch` 和 `_codedb.xml` 资源
XE2 及更高版本引擎通过安全 MSXML 解析、确定性 XPath 1 等价物以及量词、FLWOR 求和、转换、序列比较、外部代码列表、日期模式和布尔指示值直接求值,执行完整的审查 XPath 2 表面
EN 16931 配置文件包含 618 项检查,每次验证运行都会处理每项检查
组合验证
var
Report: THPDFEInvoiceValidationReport;
begin
if not HPDFValidateEInvoice(PDF,
'Lib\resources\Schematron', Report) then
LogValidationFailure(Report);
end;
HPDFValidateEInvoice 首先调用 THotPDF.ValidateFacturXInvoice,提取并识别发票 XML,加载配置文件特定的 Schematron 资源,并执行业务规则
当 XML 提取、配置文件检测、规则加载、代码数据库加载或表达式求值无法完成时,检测到的混合发票会失败关闭
仅当容器有效、业务规则已求值且没有剩余错误或警告发现时,函数才返回 true
配置文件注册表与验证范围
THPDFEInvoiceRuleRegistry 为每个 profile 注册一个业务规则层,并在需要时注册一个国家规则层,带显式的资源名、规则版本和可选的 IHPDFESchematronEngine 实现
默认注册表包含五个随库发布的 Factur-X profile,以及法国 profile EXTENDED-CTC-FR 和 EXTENDED-B2B-FR 的基础 EXTENDED 规则
法国 profile 需要额外注册国家规则层,ValidationComplete 才会变为 true;XRECHNUNG 则同时需要 EN 16931 CII 规则和德国国家规则
未知 profile 没有默认规则,也绝不会回退到 EXTENDED;对未知或特定国家的 profile,HPDFSchematronFileForProfile 返回空字符串
HPDFValidateEInvoiceWithRegistry 使用调用方的注册表配合 PDF 容器检查,而 HPDFValidateEInvoiceXML 验证显式的 XML 字节和 profile,不求值 PDF 容器
报告暴露 ProfileSupported、CountryRulesRequired、CountryRulesEvaluated、ValidationComplete 和 ValidationNote,其 RuleSets 数组记录每个所选资源、版本、范围、摘要和完成状态
完成求值的规则层仍可能包含业务规则违规,因此除了 ValidationComplete,还要检查布尔结果或 BusinessRuleViolations
这些 API 报告业务和国家规则覆盖情况;XML Schema 验证、传输策略和法律上的接受决定不在此范围内
官方 XRechnung CII 规则
HPDFEInvoiceSaxon 提供可选的 Saxon HE 桥接,执行 Lib/resources/Schematron/XRechnung 中未经修改的 EN 16931 CII 1.3.16 与 XRechnung 3.0.2 编译版 Schematron 2.6.0 样式表
资源来自 2026 年 8 月 31 日的官方 KoSIT validator 配置,资源 README 记录了它们的来源、许可证和哈希
宿主显式提供 Java 可执行文件和 Saxon class path;库启动转换时不经过 shell、不显示控制台窗口,强制超时,解析 SVRL 发现,并清理自己的临时文件
超时为零时取 60 秒,超过 3,600,000 毫秒的值被拒绝;诊断输出上限 8 MiB,编译后的样式表和 SVRL 报告在解析或加载前上限 64 MiB
uses HPDFEInvoiceValidator, HPDFEInvoiceSaxon;
Registry := THPDFEInvoiceRuleRegistry.Create;
try
Engine := HPDFCreateSaxonSchematronEngine(
JavaExecutable, SaxonClassPath, 60000);
HPDFRegisterXRechnungRules(Registry, Engine);
Valid := HPDFValidateEInvoiceWithRegistry(PDF,
'Lib\resources\Schematron', Registry, Report);
finally
Registry.Free;
end;
配置 Saxon class path 时需要带上 Saxon HE 及其必需依赖;每个验证线程使用独立的注册表和引擎实例
可选桥接要求 Windows 上的 Delphi XE2 或更高版本,以及宿主提供的 Java/Saxon 运行时;库既不下载也不安装这些运行时
运行时缺失、发票语法不对、被禁止的 DTD、超时、转换失败和畸形 SVRL 输出,都会产生显式的验证未完成诊断
官方法国 CTC 发票规则
HPDFRegisterFrenchCTCRules 选择来自 FNFE-MPE 1.4.0.04 发布版(2026 年 9 月 4 日发布,对应 AFNOR XP Z12-012 1.4 版)的官方 profile 层和严格的 BR-FR-Flux2 国家层
官方 FNFE-MPE 发布版以 Apache 2.0 发布,并由 FNFE-MPE 资源页链接;随附的 EN 16931 CII 样式表保留 EUPL 1.2,原始的编译样式表、Schematron 源、代码数据库、许可证、源路径和哈希都原样保存在 Lib/resources/Schematron/France 下
对 fisFacturX,辅助函数使用已发布的 Factur-X 1.09.2 规则层支持 BASIC WL、EN 16931 和 EXTENDED;EXTENDED-CTC-FR 容器命名使用同一 Factur-X EXTENDED 层加上法国国家检查
对独立的 fisCII,它支持 EN 16931 和专用的 EXTENDED-CTC-FR CII 层;后者的限制和 guideline 标识符与混合 Factur-X EXTENDED 层不同
Engine := HPDFCreateSaxonSchematronEngine(
JavaExecutable, SaxonClassPath, 60000);
HPDFRegisterFrenchCTCRules(Registry, 'EN 16931',
Engine, fisFacturX);
Valid := HPDFValidateEInvoiceWithRegistry(PDF,
'Lib\resources\Schematron', Registry, Report);
HPDFRegisterFrenchCTCRules(Registry, 'EXTENDED-CTC-FR',
Engine, fisCII);
Valid := HPDFValidateEInvoiceXML(XMLBytes, 'EXTENDED-CTC-FR',
'Lib\resources\Schematron', Registry, Report);
注册会保留独立的 profile 与国家规则版本,并把法国国家层设为所选 profile 的必需层;显式为法国注册时,EN 16931 和 BASIC WL 也是如此
直接使用严格发布的国家样式表,不会替换成单独的仅警告变体,也不会降级发现
锁定的官方包没有 EXTENDED-B2B-FR 规则 profile,因此辅助函数拒绝这个遗留名称,而不是把它当作自动认证的别名
验证成功表明这些已发布的发票业务规则层执行完毕;XML Schema、CDAR 生命周期消息、e-reporting 数据提取、平台授权、传输和法律认证仍是独立的范围
引擎 API
Engine := HPDFCreateSchematronEngine;
if not Engine.Load(SchematronPath, ErrorText) then
raise Exception.Create(ErrorText);
Findings := Engine.Validate(XMLBytes);
Summary := Engine.LastSummary;
THPDFSchematronSummary 报告 Profile、TotalRules、Evaluated、Skipped、EvaluationErrors、Violations、EngineAvailable 和 EngineNote
Skipped 在 XE2 及更高版本引擎中保持为零,并保留给 Delphi 7 桩或遗留结果数据
格式错误或不受支持的表达式产生显式错误严重性发现,递增 EvaluationErrors,并且永远不会作为成功检查消失
Factur-X XML 辅助函数
HPDFFacturX 单元提供按字节读取 Factur-X / ZUGFeRD 发票 XML 的辅助函数,不构建 DOM,因此在本库支持的每个 Delphi 版本上都能运行,对 ExtractFacturXXML 提取出的字节也是安全的
HPDFFacturXGuidelineIDFromXMLBytes(XMLBytes) 从 CII 文档的 GuidelineSpecifiedDocumentContextParameter / ram:ID 元素返回 guideline 标识符,缺失时返回空字符串
HPDFIsFacturXConformanceLevel(Value, FileName, Version) 验证一致性级别名称,接受 MINIMUM、BASIC WL、BASIC、EN 16931、EN16931、EXTENDED、EXTENDED-CTC-FR、EXTENDED-B2B-FR 和 XRECHNUNG;遗留的 COMFORT 级别还要求文件名为 ZUGFeRD 1.0 的 ZUGFeRD-invoice.xml 且版本为 1.0
HPDFFacturXXMLGuidelineOK(XMLBytes, ConformanceLevel, Version, FileName) 把 XML 中找到的 guideline 与声明的一致性级别、版本和内嵌文件名交叉核对
HPDFFacturXInvoiceSummaryFromXML(XMLBytes, out ASummary) 从发票 XML 填充 THPDFFacturXInvoiceSummary 记录,至少定位到主发票 XML 时返回 True;该摘要记录类型本身声明在 HPDFDoc 中,位于 THPDFFacturXInvoiceInfo 旁边
稳定诊断与限制
- 规则标识符在存在时从 Schematron 消息令牌解析
- 缺失的标识符接收确定性配置文件和断言或报告序号
- 每个发现保留其原始上下文和测试表达式
- 外部代码数据库路径限制为同级文件名
- 禁用 DTD 处理和外部 XML 实体解析
- 发票 XML 输入限制为 64 MiB
工具链可用性
Delphi XE2 及更高版本使用内置 MSXML 兼容引擎
Delphi 7 保留共享接口和结果类型,但返回引擎不可用诊断
相关 API
HPDFValidateEInvoiceHPDFValidateEInvoiceWithRegistryHPDFValidateEInvoiceXMLTHPDFEInvoiceRuleRegistryHPDFRegisterXRechnungRulesHPDFRegisterFrenchCTCRulesTHPDFFrenchInvoiceSyntaxHPDFCreateSchematronEngineHPDFSchematronFileForProfileIHPDFESchematronEngineTHPDFBusinessRuleResultTHPDFSchematronSummary- THotPDF.ValidateFacturXInvoice
- THotPDF.ExtractFacturXXML
非 GUI 验收
运行 Tests/Delphi/Run-EInvoiceRuleTests.ps1 时显式给出 JavaExecutable 和 SaxonClassPath,或设置对应的 HOTPDF_JAVA_EXE 和 HOTPDF_SAXON_CLASSPATH 环境变量
默认 runner 要求官方规则引擎配置,并在抑制 PDF 阅读器启动的前提下同时跑 Win32 和 Win64;-NativeOnly 会刻意跳过官方 Saxon 执行