pain001.schematron package#

ISO Schematron (ISO/IEC 19757-3) business rules validation for ISO 20022 payments.

Submodules#

pain001.schematron.evaluator module#

XPath expression evaluator for Schematron assertions in ISO 20022 messages.

class pain001.schematron.evaluator.XPathEvaluator(node: Element, namespaces: dict[str, str])[source]#

Bases: object

Recursive descent evaluator for Schematron XPath assertion expressions.

evaluate(expr_str: str) → bool[source]#

Evaluate an expression string against the node, returning a boolean.

pain001.schematron.evaluator.evaluate_assertion(assertion: SchematronAssertion, node: Element, context_path: str, namespaces: dict[str, str]) → SchematronViolation | None[source]#

Evaluate a single Schematron assertion against an XML node.

Returns a SchematronViolation if the assertion fails, or None if it passes.

pain001.schematron.evaluator.find_context_elements(root: Element, context_expr: str, namespaces: dict[str, str]) → list[Element][source]#

Find all elements in the XML document matching a Schematron rule context.

Parameters:
  • root – The XML root element.

  • context_expr – Context XPath expression (e.g. ‘//pain:CdtTrfTxInf’, ‘pain:PmtInf’).

  • namespaces – Mapping of namespace prefixes to URIs.

Returns:

List of matching Element instances.

pain001.schematron.evaluator.resolve_xpath_value(node: Element, path: str, namespaces: dict[str, str]) → Any[source]#

Resolve a relative XPath expression on an element node.

Returns string value, number, list of elements, or None.

pain001.schematron.models module#

Data models and diagnostics for Schematron business rules validation.

pain001.schematron.models.REMEDIATIONS: dict[str, str] = {'CBPR-TX-001': 'Specify a valid 3-letter ISO 4217 currency code.', 'CBPR-TX-002': 'Ensure transaction amount is strictly positive.', 'CBPR-TX-003': 'Provide a non-empty EndToEndId for cross-border tracing.', 'CBPR-TX-004': 'Ensure UETR matches the 36-character canonical UUID format.', 'CBPR-TX-005': 'Provide a valid 8 or 11 character BICFI for the creditor agent.', 'EPC-PMT-001': 'Provide an IBAN for the debtor account.', 'EPC-PMT-002': "Set payment service level code SvcLvl/Cd to 'SEPA'.", 'EPC-PMT-003': "Set payment level ChrgBr (Charge Bearer) to 'SLEV'.", 'EPC-SCT-001': "Set currency attribute to 'EUR' on InstdAmt.", 'EPC-SCT-002': "Set ChrgBr (Charge Bearer) to 'SLEV'.", 'EPC-SCT-003': 'Provide an IBAN for the creditor account.', 'EPC-SCT-004': 'Ensure transaction amount is strictly positive.', 'EPC-SCT-005': 'Reduce transaction amount below 999,999,999.99 EUR.', 'EPC-SCT-006': 'Provide a valid 8 or 11 character BICFI for the creditor agent or omit it.', 'EPC-SCT-007': "Provide a non-empty EndToEndId (must not be 'NOTPROVIDED').", 'FDN-PMT-001': "Specify 'FDN' for clearing system provider or service level.", 'FDN-TX-001': "Set currency attribute to 'USD' on InstdAmt.", 'FDN-TX-002': "Set ChrgBr to 'DEBT' or 'SHAR' for FedNow instant transfers.", 'FDN-TX-003': 'Ensure transaction amount is strictly positive.', 'FDN-TX-004': 'Split transfer or reduce amount to stay within FedNow $1,000,000.00 ceiling.', 'FDN-TX-005': 'Provide a unique EndToEndId for the FedNow payment.'}#

Remediation hints for Schematron business rule IDs.

class pain001.schematron.models.SchematronValidationResult(is_valid: bool, rulebook: str, violations: list[~pain001.schematron.models.SchematronViolation] = <factory>, rules_evaluated: int = 0, rules_passed: int = 0, duration_ms: float = 0.0)[source]#

Bases: object

The aggregate result of a Schematron rulebook evaluation.

Variables:
  • is_valid (bool) – True if no ERROR-level violations were found.

  • rulebook (str) – Name of the evaluated rulebook or schema path.

  • violations (list[pain001.schematron.models.SchematronViolation]) – List of all violations discovered.

  • rules_evaluated (int) – Total count of assertions evaluated.

  • rules_passed (int) – Total count of assertions that passed.

  • duration_ms (float) – Evaluation duration in milliseconds.

duration_ms: float = 0.0#
property error_count: int#

Count of ERROR-level violations.

format_report(detailed: bool = True) → str[source]#

Format a human-readable text report of the validation outcome.

is_valid: bool#
rulebook: str#
rules_evaluated: int = 0#
rules_passed: int = 0#
to_dict() → dict[str, Any][source]#

Convert result to JSON-serializable dictionary.

violations: list[SchematronViolation]#
property warning_count: int#

Count of WARNING-level violations.

class pain001.schematron.models.SchematronViolation(rule_id: str, message: str, context: str, test: str, line_number: int | None = None, severity: str = 'ERROR', remediation: str = '')[source]#

Bases: object

A single rule assertion violation discovered by the Schematron engine.

Variables:
  • rule_id (str) – Identifying code for the rule (e.g., ‘EPC-SCT-001’).

  • message (str) – Human-readable message explaining the assertion failure.

  • context (str) – XPath context where the violation occurred.

  • test (str) – The Schematron test expression that evaluated to false.

  • line_number (int | None) – Line number in the XML document if available.

  • severity (str) – ‘ERROR’ or ‘WARNING’.

  • remediation (str) – Guidance on how to fix the violation.

context: str#
line_number: int | None = None#
message: str#
remediation: str = ''#
rule_id: str#
severity: str = 'ERROR'#
test: str#
to_dict() → dict[str, Any][source]#

Convert violation to JSON-serializable dictionary.

pain001.schematron.models.remediation_for(rule_id: str) → str[source]#

Return remediation hint for a Schematron rule ID.

pain001.schematron.parser module#

Parser for ISO Schematron (ISO/IEC 19757-3) schema files.

class pain001.schematron.parser.SchematronAssertion(rule_id: str, test: str, message: str, is_report: bool = False, severity: str = 'ERROR')[source]#

Bases: object

A single assert or report statement within a Schematron rule.

Variables:
  • rule_id (str) – Unique rule identifier (from id or rule attribute).

  • test (str) – The XPath test expression.

  • message (str) – Human-readable error/diagnostic message.

  • is_report (bool) – True if this is a <report> (fails when test is true).

  • severity (str) – ‘ERROR’ or ‘WARNING’.

is_report: bool = False#
message: str#
rule_id: str#
severity: str = 'ERROR'#
test: str#
class pain001.schematron.parser.SchematronPattern(pattern_id: str, title: str, rules: list[~pain001.schematron.parser.SchematronRule] = <factory>)[source]#

Bases: object

A pattern element grouping related rules.

pattern_id: str#
rules: list[SchematronRule]#
title: str#
class pain001.schematron.parser.SchematronRule(context: str, assertions: list[~pain001.schematron.parser.SchematronAssertion] = <factory>)[source]#

Bases: object

A rule element specifying context and containing assertions.

assertions: list[SchematronAssertion]#
context: str#
class pain001.schematron.parser.SchematronSchema(title: str, namespaces: dict[str, str] = <factory>, patterns: list[~pain001.schematron.parser.SchematronPattern] = <factory>)[source]#

Bases: object

Parsed representation of an entire Schematron document.

namespaces: dict[str, str]#
patterns: list[SchematronPattern]#
title: str#
property total_assertions: int#

Count all assertions across all patterns and rules.

pain001.schematron.parser.parse_schematron(source: str | bytes | Path) → SchematronSchema[source]#

Parse a Schematron (.sch) XML document into a SchematronSchema object.

Parameters:

source – XML string, bytes, or Path pointing to the .sch file.

Returns:

SchematronSchema representing parsed rules and namespaces.

Raises:

ValueError – If the source does not represent a valid Schematron document.

pain001.schematron.validator module#

High-level Schematron validator for ISO 20022 clearing network rulebooks.

pain001.schematron.validator.PRESET_RULEBOOKS: dict[str, str] = {'cbpr': 'cbpr_plus.sch', 'cbpr+': 'cbpr_plus.sch', 'cbpr-plus': 'cbpr_plus.sch', 'epc-sepa': 'epc_sepa.sch', 'fednow': 'fednow.sch', 'sepa': 'epc_sepa.sch', 'sepa-sct': 'epc_sepa.sch', 'swift': 'cbpr_plus.sch'}#

Mapping of friendly preset names to packaged rulebook .sch files.

class pain001.schematron.validator.SchematronValidator(rulebook_or_path: str | Path = 'sepa')[source]#

Bases: object

Validates ISO 20022 XML messages against Schematron business rules.

Parameters:

rulebook_or_path – Friendly preset name (‘sepa’, ‘fednow’, ‘cbpr’) or Path to a custom .sch file.

validate(xml_input: str | bytes | Path | Element) → SchematronValidationResult[source]#

Validate an XML document against the loaded Schematron schema.

Parameters:

xml_input – XML string, raw bytes, file Path, or ElementTree Element.

Returns:

SchematronValidationResult with pass/fail verdict and violations.

Raises:

ValueError – If the input XML cannot be parsed.

pain001.schematron.validator.resolve_rulebook_path(rulebook_or_path: str | Path) → Path[source]#

Resolve a rulebook preset name or filesystem path to a Path object.

Parameters:

rulebook_or_path – Friendly name (‘sepa’, ‘fednow’) or path to .sch file.

Returns:

Resolved Path to the Schematron schema.

Raises:

FileNotFoundError – If the specified rulebook or schema cannot be found.

pain001.schematron.validator.validate_schematron(xml_input: str | bytes | Path | Element, rulebook: str | Path = 'sepa') → SchematronValidationResult[source]#

Convenience function to validate an XML document against a Schematron rulebook.

Parameters:
  • xml_input – XML string, raw bytes, file Path, or ElementTree Element.

  • rulebook – Friendly preset (‘sepa’, ‘fednow’, ‘cbpr’) or path to .sch file.

Returns:

SchematronValidationResult containing diagnostics and pass/fail verdict.