E-Invoice Business-Rule Validation
HPDFEInvoiceValidator combines Factur-X or ZUGFeRD container validation with explicitly selected, versioned business-rule and country-rule sets
Complete reviewed rule execution
The library ships matching `.sch` and `_codedb.xml` resources for MINIMUM, BASIC WL, BASIC, EN 16931 and EXTENDED
The XE2 and later engine executes the complete reviewed XPath 2 surface through secure MSXML parsing, deterministic XPath 1 equivalents, and direct evaluation for quantifiers, FLWOR sums, casts, sequence comparisons, external code lists, date patterns and boolean indicator values
The EN 16931 profile contains 618 checks and every check is processed during each validation run
Combined validation
var
Report: THPDFEInvoiceValidationReport;
begin
if not HPDFValidateEInvoice(PDF,
'Lib\resources\Schematron', Report) then
LogValidationFailure(Report);
end;
HPDFValidateEInvoice first calls THotPDF.ValidateFacturXInvoice, extracts and identifies the invoice XML, loads the profile-specific Schematron resources, and executes the business rules
A detected hybrid invoice fails closed when XML extraction, profile detection, rule loading, code-database loading or expression evaluation cannot complete
The function returns true only when the container is valid, business rules were evaluated, and no error or warning finding remains
Profile registry and validation scope
THPDFEInvoiceRuleRegistry registers one business-rule layer and, when required, one country-rule layer per profile, with an explicit resource name, rule version, and optional IHPDFESchematronEngine implementation
The default registry contains the five shipped Factur-X profiles and the base EXTENDED rules for the French profiles EXTENDED-CTC-FR and EXTENDED-B2B-FR
The French profiles require an additional country-rule registration before ValidationComplete becomes true, and XRECHNUNG requires both EN 16931 CII and German country rules
Unknown profiles have no default rules and never fall back to EXTENDED, and HPDFSchematronFileForProfile returns an empty string for unknown or country-specific profiles
HPDFValidateEInvoiceWithRegistry uses the caller's registry with the PDF container check, whilst HPDFValidateEInvoiceXML validates explicit XML bytes and a profile without evaluating a PDF container
The report exposes ProfileSupported, CountryRulesRequired, CountryRulesEvaluated, ValidationComplete, and ValidationNote, and its RuleSets array records each selected resource, version, scope, summary, and completion status
A completed rule evaluation can still contain business-rule violations, so check the Boolean result or BusinessRuleViolations as well as ValidationComplete
These APIs report business and country rule coverage, whilst XML Schema validation, transport policies, and legal acceptance decisions remain outside this scope
Official XRechnung CII rules
HPDFEInvoiceSaxon supplies an optional Saxon HE bridge that executes the unmodified compiled EN 16931 CII 1.3.16 and XRechnung 3.0.2 Schematron 2.6.0 stylesheets shipped in Lib/resources/Schematron/XRechnung
The resources come from the official KoSIT validator configuration dated 31 August 2026, and the resource README records their provenance, licences, and hashes
The host supplies the Java executable and Saxon class path explicitly, and the library launches the transformation without a shell or a visible console window, enforces a timeout, parses SVRL findings, and removes its temporary files
A zero timeout selects 60 seconds, values above 3,600,000 milliseconds are rejected, diagnostic output is capped at 8 MiB, and compiled stylesheets and SVRL reports are capped at 64 MiB before parsing or loading
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;
Configure the Saxon class path with Saxon HE and its required dependencies, and use a separate registry and engine instance per validation thread
The optional bridge requires Delphi XE2 or later on Windows and a host-provided Java/Saxon runtime, and neither runtime is downloaded or installed by the library
Missing runtimes, wrong invoice syntax, prohibited DTDs, timeout, failed transformation, and malformed SVRL output produce explicit incomplete-validation diagnostics
Official French CTC invoice rules
HPDFRegisterFrenchCTCRules selects the official profile layer and the strict BR-FR-Flux2 country layer from FNFE-MPE release 1.4.0.04, published 4 September 2026 for AFNOR XP Z12-012 version 1.4
The official FNFE-MPE release is published under Apache 2.0 and linked by the FNFE-MPE resource page, whilst the included EN 16931 CII stylesheet retains EUPL 1.2, and the original compiled stylesheets, Schematron sources, code databases, licences, source paths, and hashes are preserved under Lib/resources/Schematron/France
For fisFacturX, the helper supports BASIC WL, EN 16931, and EXTENDED using the published Factur-X 1.09.2 rule layers, and the EXTENDED-CTC-FR container designation uses the same Factur-X EXTENDED layer plus the French country checks
For standalone fisCII, it supports EN 16931 and the dedicated EXTENDED-CTC-FR CII layer, whose restrictions and guideline identifier differ from the hybrid Factur-X EXTENDED layer
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);
Registration preserves separate profile and country-rule versions and makes the French country layer required for the selected profile, including EN 16931 and BASIC WL when explicitly registered for France
The strict published national stylesheet is used directly, without substituting the separate warning-only variant or downgrading findings
The pinned official package has no EXTENDED-B2B-FR rule profile, so the helper rejects that legacy name instead of treating it as an automatically certified alias
Successful validation establishes completion of these published invoice business-rule layers, whilst XML Schema, CDAR lifecycle messages, e-reporting data extraction, platform authorisation, transport, and legal certification remain separate scopes
Engine API
Engine := HPDFCreateSchematronEngine;
if not Engine.Load(SchematronPath, ErrorText) then
raise Exception.Create(ErrorText);
Findings := Engine.Validate(XMLBytes);
Summary := Engine.LastSummary;
THPDFSchematronSummary reports Profile, TotalRules, Evaluated, Skipped, EvaluationErrors, Violations, EngineAvailable and EngineNote
Skipped remains zero in the XE2 and later engine and is reserved for the Delphi 7 stub or legacy result data
Malformed or unsupported expressions produce explicit error-severity findings, increment EvaluationErrors and never disappear as successful checks
Factur-X XML helper functions
The HPDFFacturX unit ships byte-level helpers that read a Factur-X / ZUGFeRD invoice XML without building a DOM, so they run on every Delphi version the library supports and are safe on extracted bytes from ExtractFacturXXML
HPDFFacturXGuidelineIDFromXMLBytes(XMLBytes) returns the guideline identifier from the GuidelineSpecifiedDocumentContextParameter / ram:ID element of a CII document, or an empty string when absent
HPDFIsFacturXConformanceLevel(Value, FileName, Version) validates a conformance level name, accepting MINIMUM, BASIC WL, BASIC, EN 16931, EN16931, EXTENDED, EXTENDED-CTC-FR, EXTENDED-B2B-FR, and XRECHNUNG; the legacy COMFORT level additionally requires the ZUGFeRD 1.0 file name ZUGFeRD-invoice.xml with version 1.0
HPDFFacturXXMLGuidelineOK(XMLBytes, ConformanceLevel, Version, FileName) cross-checks the guideline found in the XML against the declared conformance level, version, and embedded file name
HPDFFacturXInvoiceSummaryFromXML(XMLBytes, out ASummary) fills a THPDFFacturXInvoiceSummary record from the invoice XML and returns True when at least the primary invoice XML could be located; the summary record type itself is declared in HPDFDoc next to THPDFFacturXInvoiceInfo
Stable diagnostics and limits
- Rule identifiers are parsed from the Schematron message token when present
- Missing identifiers receive deterministic profile and assertion-or-report ordinals
- Each finding preserves its original context and test expressions
- External code-database paths are restricted to sibling file names
- DTD processing and external XML entity resolution are disabled
- Invoice XML input is limited to 64 MiB
Toolchain availability
Delphi XE2 and later use the built-in MSXML compatibility engine
Delphi 7 retains the shared interfaces and result types but returns an unavailable-engine diagnostic
Related APIs
HPDFValidateEInvoiceHPDFValidateEInvoiceWithRegistryHPDFValidateEInvoiceXMLTHPDFEInvoiceRuleRegistryHPDFRegisterXRechnungRulesHPDFRegisterFrenchCTCRulesTHPDFFrenchInvoiceSyntaxHPDFCreateSchematronEngineHPDFSchematronFileForProfileIHPDFESchematronEngineTHPDFBusinessRuleResultTHPDFSchematronSummary- THotPDF.ValidateFacturXInvoice
- THotPDF.ExtractFacturXXML
Non-GUI acceptance
Run Tests/Delphi/Run-EInvoiceRuleTests.ps1 with explicit JavaExecutable and SaxonClassPath values, or the matching HOTPDF_JAVA_EXE and HOTPDF_SAXON_CLASSPATH environment variables
The default runner requires the official-rule engine configuration and runs both Win32 and Win64 with PDF viewer launch suppressed; -NativeOnly deliberately omits official Saxon execution