電子發票商務規則驗證

HPDFEInvoiceValidator 結合 Factur-X 或 ZUGFeRD 容器驗證,以及明確選取、版本化的商務規則集與國家規則集

完整的審核規則執行

此程式庫隨附 MINIMUM、BASIC WL、BASIC、EN 16931 與 EXTENDED 的相符 資源

XE2 及更新版本的引擎透過安全的 MSXML 剖析、確定性的 XPath 1 對等與直接求值來執行完整的審核 XPath 2 介面,涵蓋量詞、FLWOR 總和、轉型、序列比較、外部程式碼清單、日期模式與布林指標值

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;HPDFSchematronFileForProfile 對未知或國家專屬 profile 會回傳空字串

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 configuration,資源 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
esources\Schematron', Registry, Report);
finally
  Registry.Free;
end;

組態 Saxon class path 時請放入 Saxon HE 及其必要相依,並在每個驗證執行緒使用獨立的登錄與引擎執行個體

這個選用橋接需要 Windows 上的 Delphi XE2 或更新版本,以及宿端提供的 Java/Saxon 執行環境;兩者都不會由程式庫下載或安裝

缺少執行環境、發票語法錯誤、被禁止的 DTD、逾時、轉換失敗與格式錯誤的 SVRL 輸出,都會產生明確的未完成驗證診斷

官方法國 CTC 發票規則

HPDFRegisterFrenchCTCRules 選用 FNFE-MPE 於 2026 年 9 月 4 日為 AFNOR XP Z12-012 version 1.4 發布的 1.4.0.04 版本中的官方 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 層,其限制與準則識別碼不同於混合式 Factur-X EXTENDED 層

Engine := HPDFCreateSaxonSchematronEngine(
  JavaExecutable, SaxonClassPath, 60000);

HPDFRegisterFrenchCTCRules(Registry, 'EN 16931',
  Engine, fisFacturX);
Valid := HPDFValidateEInvoiceWithRegistry(PDF,
  'Lib
esources\Schematron', Registry, Report);

HPDFRegisterFrenchCTCRules(Registry, 'EXTENDED-CTC-FR',
  Engine, fisCII);
Valid := HPDFValidateEInvoiceXML(XMLBytes, 'EXTENDED-CTC-FR',
  'Lib
esources\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 元素回傳準則識別碼,沒有時回傳空字串

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 中找到的準則與宣告的符合層級、版本及內嵌檔名

HPDFFacturXInvoiceSummaryFromXML(XMLBytes, out ASummary) 從發票 XML 填入 THPDFFacturXInvoiceSummary 記錄,至少找到主要發票 XML 時回傳 True;該摘要記錄類型本身宣告在 HPDFDoc 中,就在 THPDFFacturXInvoiceInfo 旁邊

穩定的診斷與限制

工具鏈可用性

Delphi XE2 及更新版本使用內建的 MSXML 相容引擎

Delphi 7 保留共享的介面與結果類型,但傳回引擎不可用的診斷

相關 API

非 GUI 驗收

執行 Tests/Delphi/Run-EInvoiceRuleTests.ps1 時,請明確給出 JavaExecutable 與 SaxonClassPath,或設定對應的 HOTPDF_JAVA_EXE 與 HOTPDF_SAXON_CLASSPATH 環境變數

預設的 runner 需要官方規則引擎組態,會同時跑 Win32 與 Win64 並抑制 PDF 檢視器啟動;-NativeOnly 則刻意略過官方 Saxon 執行