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, while 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, while 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 August 31, 2026, and the resource README records their provenance, licenses, 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 September 4, 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, while the included EN 16931 CII stylesheet retains EUPL 1.2, and the original compiled stylesheets, Schematron sources, code databases, licenses, 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, while XML Schema, CDAR lifecycle messages, e-reporting data extraction, platform authorization, 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

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

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