-
Notifications
You must be signed in to change notification settings - Fork 47
Description
When the output of sepa.export() is parsed and re-serialized using Python's xml.etree.ElementTree for pretty-printing (indentation), the resulting XML contains ns0: prefixes on all elements. German banks (tested with Volksbank using DK-SEPA validator v1.13.1) reject this with 577 warnings:
Line 2, Col 2: Das Setzen von individuellen Präfixen ist unzulässig (ns0).
Line 3, Col 4: Das Setzen von individuellen Präfixen ist unzulässig (ns0).
...
Steps to reproduce
import xml.etree.ElementTree as ET
from sepaxml import SepaTransfer
import datetime
config = {
"name": "Test GmbH",
"IBAN": "DE12345678901234567890",
"BIC": "TESTDE99XXX",
"batch": True,
"currency": "EUR",
}
sepa = SepaTransfer(config, clean=True)
sepa.add_payment({
"name": "Recipient",
"IBAN": "DE98765432109876543210",
"BIC": "EMPFDE99XXX",
"amount": 1500,
"execution_date": datetime.date(2026, 3, 17),
"description": "Test",
})
xml_bytes = sepa.export(validate=True)
# Pretty-print via ElementTree
ET.register_namespace("", "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03")
root = ET.fromstring(xml_bytes)
print(ET.tostring(root, encoding="unicode")[:200])
# Output contains: <ns0:Document xmlns:ns0="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03">Root cause
ET.register_namespace() must be called before ET.fromstring(). Once the document is parsed, ElementTree has already assigned internal namespace prefixes and register_namespace() has no effect on already-parsed nodes.
Workaround
Regex-based cleanup after serialization:
import re
serialised = ET.tostring(root, encoding="unicode")
serialised = re.sub(r'<ns\d+:(\w)', r'<\1', serialised)
serialised = re.sub(r'</ns\d+:', r'</', serialised)
serialised = re.sub(r'\bxmlns:ns\d+="', 'xmlns="', serialised)Suggested fix
The library could register all its namespaces as default namespaces at module import time, so that ET.fromstring() already uses the correct prefix mapping. Alternatively, the library could expose a export(pretty=True) option that returns properly indented XML without namespace prefix issues.
Environment
- python-sepaxml version: latest (pip)
- Python: 3.12
- Tested schema: pain.001.001.03
- Validator: DK-SEPA v1.13.1 (used by German Volksbank/Raiffeisenbank)