Developers & Data 8 min readPublished · Updated

XRechnung XML Structure: UBL, CII, Namespaces and XSD

XRechnung XSD and XML structure explained for developers: UBL and CII root elements, namespaces, schema and Schematron validation, plus a BT-to-XPath table.

Max BlueFounder & Editor-in-Chief

Key takeaways

  • XRechnung 3.0.2 comes in two equivalent syntaxes: UBL 2.1 with the root element Invoice or CreditNote, and UN/CEFACT CII D16B with rsm:CrossIndustryInvoice.
  • There is no separate XRechnung XSD; files are checked against UBL-Invoice-2.1.xsd, UBL-CreditNote-2.1.xsd or CrossIndustryInvoice_100pD16B.xsd, then against the EN 16931 and KoSIT Schematron rules.
  • For every 3.0.x release, BT-24 is urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0, and BT-23 (business process) is mandatory under rule PEPPOL-EN16931-R001.
  • UBL writes dates as 2026-09-28, CII as 20260928 with format code 102; invoice amounts use a dot as decimal separator and at most two decimal places.
  • The buyer reference BT-10 sits in cbc:BuyerReference in UBL and in ram:ApplicableHeaderTradeAgreement/ram:BuyerReference in CII; if it is missing, the validator reports BR-DE-15.
On this page

There is no separate XRechnung XSD. An XRechnung is an XML file in UBL 2.1 (root element Invoice or CreditNote) or UN/CEFACT CII D16B (root rsm:CrossIndustryInvoice), and it is validated against the XSD of that syntax. After the schema check come the EN 16931 Schematron rules and KoSIT's XRechnung rules; only a file that passes all three is valid.

Last reviewed: September 2026 · Based on XRechnung 3.0.2

This guide is for developers who generate, parse or validate XRechnung files. It covers both document skeletons, the namespaces, a mapping of the key business terms to XPath, and the mistakes that most often get a file rejected. If you first need the business context (what XRechnung is and who has to use it), start with What is XRechnung?. More developer articles are collected under developer tools.

Which syntaxes does XRechnung allow?

XRechnung is Germany's Core Invoice Usage Specification (CIUS) of the European standard EN 16931. It is published by KoSIT, the German Coordination Office for IT Standards. The standard defines a semantic invoice model made of business terms such as BT-1 (invoice number) and business groups such as BG-25 (invoice line). A syntax binding defines which XML element carries which business term. There are two bindings: UBL 2.1 and CII version D16B. Both are equally valid forms of XRechnung.

PropertyUBL 2.1UN/CEFACT CII D16B
Root elementInvoice, or CreditNote for credit notesrsm:CrossIndustryInvoice
Root namespaceurn:oasis:names:specification:ubl:schema:xsd:Invoice-2 or …:CreditNote-2urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100
XSD fileUBL-Invoice-2.1.xsd, UBL-CreditNote-2.1.xsdCrossIndustryInvoice_100pD16B.xsd
Credit note (code 381)separate document type with cbc:CreditNoteTypeCodesame root, code in ram:TypeCode
Date format2026-09-2820260928 with format="102"
Invoice linesat the end of the documentat the start of rsm:SupplyChainTradeTransaction
Where you meet itPeppol BIS Billing 3.0 is built on UBLXML part of ZUGFeRD and Factur-X

No law prescribes one or the other. If you send via Peppol, UBL is the usual choice. If you already produce ZUGFeRD, CII lets you reuse that structure. The comparison UBL vs. CII goes into the differences, and XRechnung vs. ZUGFeRD explains how the two formats relate.

The current version is XRechnung 3.0.2; the latest bundle, "3.0.2 Summer 2026 Bugfix", is dated 31 August 2026. Version 3.0 has applied since 1 February 2024 and remains in force until at least 31 July 2027. KoSIT published a pre-release of XRechnung 4.0 in September 2026, and the final version is expected in spring 2027. KoSIT keeps these dates on its versions and bundles page (opens in a new tab) (in German).

Which namespaces does an XRechnung need?

A namespace is a URI that names an XML vocabulary. The prefix in front of an element is only a local alias. A namespace-aware parser always compares the pair of URI and local name, so <Invoice xmlns="…Invoice-2"> and <ubl:Invoice xmlns:ubl="…Invoice-2"> are the same element to any validator. The reverse also holds: the right prefix does not help if the URI is off by a single character.

PrefixNamespace URIContains
none or ublurn:oasis:names:specification:ubl:schema:xsd:Invoice-2the UBL invoice root
cacurn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2composite elements such as cac:AccountingSupplierParty, cac:InvoiceLine
cbcurn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2simple values such as cbc:ID, cbc:IssueDate
rsmurn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100the CII root and its three main blocks
ramurn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100almost all business elements in CII
udturn:un:unece:uncefact:data:standard:UnqualifiedDataType:100data types such as udt:DateTimeString, udt:Indicator
qdturn:un:unece:uncefact:data:standard:QualifiedDataType:100qualified data types, e.g. formatted dates

A typo in one of these URIs is easy to miss. The file stays well-formed, but no schema matches it any more. The KoSIT validator then finds no validation scenario and rejects the file. The error page SCHEMA-002 explains this case.

What does a UBL XRechnung look like?

UBL is flat. Header data comes first, followed by references, the parties, delivery and payment details, the VAT breakdown, the totals and finally the invoice lines. The XSD defines this order as a sequence. A correctly named element in the wrong position is a schema error: put cbc:IssueDate after cbc:InvoiceTypeCode and the file already fails the XSD.

<?xml version="1.0" encoding="UTF-8"?>
<ubl:Invoice xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
    xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
  <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID> <!-- BT-24 -->
  <cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID> <!-- BT-23 -->
  <cbc:ID>RE-2026-0815</cbc:ID>                                   <!-- BT-1 -->
  <cbc:IssueDate>2026-09-28</cbc:IssueDate>                       <!-- BT-2 -->
  <cbc:DueDate>2026-10-12</cbc:DueDate>                           <!-- BT-9 -->
  <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>                  <!-- BT-3 -->
  <cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>        <!-- BT-5 -->
  <cbc:BuyerReference>991-12345-73</cbc:BuyerReference>           <!-- BT-10 -->
  <cac:AccountingSupplierParty>…</cac:AccountingSupplierParty>    <!-- BG-4 seller -->
  <cac:AccountingCustomerParty>…</cac:AccountingCustomerParty>    <!-- BG-7 buyer -->
  <cac:PaymentMeans>…</cac:PaymentMeans>                          <!-- BG-16 -->
  <cac:TaxTotal>…</cac:TaxTotal>                                  <!-- BT-110, BG-23 -->
  <cac:LegalMonetaryTotal>                                        <!-- BG-22 -->
    <cbc:LineExtensionAmount currencyID="EUR">1500.00</cbc:LineExtensionAmount> <!-- BT-106 -->
    <cbc:TaxExclusiveAmount currencyID="EUR">1500.00</cbc:TaxExclusiveAmount>   <!-- BT-109 -->
    <cbc:TaxInclusiveAmount currencyID="EUR">1785.00</cbc:TaxInclusiveAmount>   <!-- BT-112 -->
    <cbc:PayableAmount currencyID="EUR">1785.00</cbc:PayableAmount>             <!-- BT-115 -->
  </cac:LegalMonetaryTotal>
  <cac:InvoiceLine>                                               <!-- BG-25 -->
    <cbc:ID>1</cbc:ID>                                            <!-- BT-126 -->
    <cbc:InvoicedQuantity unitCode="HUR">15</cbc:InvoicedQuantity> <!-- BT-129, BT-130 -->
    <cbc:LineExtensionAmount currencyID="EUR">1500.00</cbc:LineExtensionAmount> <!-- BT-131 -->
    <cac:Item>
      <cbc:Name>Consulting services September 2026</cbc:Name>     <!-- BT-153 -->
      <cac:ClassifiedTaxCategory>…</cac:ClassifiedTaxCategory>    <!-- BG-30 -->
    </cac:Item>
    <cac:Price>
      <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount>  <!-- BT-146 -->
    </cac:Price>
  </cac:InvoiceLine>
</ubl:Invoice>

Two details stand out. Every amount in UBL carries a currencyID attribute; leave it out and the XSD already complains. And a credit note is its own document type: CreditNote with cbc:CreditNoteTypeCode, cac:CreditNoteLine and cbc:CreditedQuantity. For a complete, valid file with parties and the tax block, see our xrechnung example.

What does a CII XRechnung look like?

CII splits the invoice into three blocks. rsm:ExchangedDocumentContext holds the identifiers BT-23 and BT-24. rsm:ExchangedDocument holds the invoice number, type and date. rsm:SupplyChainTradeTransaction holds everything else: first the invoice lines, then the agreement (parties, buyer reference, referenced documents), the delivery and the settlement. Developers coming from UBL are often surprised that the lines come before the header details, but the schema requires this order.

<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice
    xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
    xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
    xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
    xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:BusinessProcessSpecifiedDocumentContextParameter>
      <ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>   <!-- BT-23 -->
    </ram:BusinessProcessSpecifiedDocumentContextParameter>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID> <!-- BT-24 -->
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>RE-2026-0815</ram:ID>                                    <!-- BT-1 -->
    <ram:TypeCode>380</ram:TypeCode>                                 <!-- BT-3 -->
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20260928</udt:DateTimeString> <!-- BT-2 -->
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <ram:IncludedSupplyChainTradeLineItem>…</ram:IncludedSupplyChainTradeLineItem> <!-- BG-25 -->
    <ram:ApplicableHeaderTradeAgreement>
      <ram:BuyerReference>991-12345-73</ram:BuyerReference>          <!-- BT-10 -->
      <ram:SellerTradeParty>…</ram:SellerTradeParty>                 <!-- BG-4 -->
      <ram:BuyerTradeParty>…</ram:BuyerTradeParty>                   <!-- BG-7 -->
    </ram:ApplicableHeaderTradeAgreement>
    <ram:ApplicableHeaderTradeDelivery>…</ram:ApplicableHeaderTradeDelivery> <!-- BG-13 -->
    <ram:ApplicableHeaderTradeSettlement>
      <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>         <!-- BT-5 -->
      <ram:SpecifiedTradeSettlementPaymentMeans>…</ram:SpecifiedTradeSettlementPaymentMeans> <!-- BG-16 -->
      <ram:ApplicableTradeTax>…</ram:ApplicableTradeTax>             <!-- BG-23 -->
      <ram:SpecifiedTradePaymentTerms>…</ram:SpecifiedTradePaymentTerms> <!-- BT-9, BT-20 -->
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:LineTotalAmount>1500.00</ram:LineTotalAmount>           <!-- BT-106 -->
        <ram:TaxBasisTotalAmount>1500.00</ram:TaxBasisTotalAmount>   <!-- BT-109 -->
        <ram:TaxTotalAmount currencyID="EUR">285.00</ram:TaxTotalAmount> <!-- BT-110 -->
        <ram:GrandTotalAmount>1785.00</ram:GrandTotalAmount>         <!-- BT-112 -->
        <ram:DuePayableAmount>1785.00</ram:DuePayableAmount>         <!-- BT-115 -->
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
    </ram:ApplicableHeaderTradeSettlement>
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

Unlike UBL, CII normally puts currencyID only on ram:TaxTotalAmount; all other amounts refer to the invoice currency in BT-5. If you have a ZUGFeRD invoice, you can extract XML from PDF files with our extractor and compare the embedded CII with this skeleton.

Where is each field? Business terms mapped to XPath

The table maps the most important business terms to both syntaxes. The paths are XPath expressions relative to the root element. Three abbreviations keep the CII column readable:

  • HA means rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement
  • HS means rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement
  • MS means HS/ram:SpecifiedTradeSettlementHeaderMonetarySummation
BTMeaningUBLCII
BT-1Invoice numbercbc:IDrsm:ExchangedDocument/ram:ID
BT-2Issue datecbc:IssueDatersm:ExchangedDocument/ram:IssueDateTime/udt:DateTimeString
BT-3Invoice type codecbc:InvoiceTypeCodersm:ExchangedDocument/ram:TypeCode
BT-5Invoice currencycbc:DocumentCurrencyCodeHS/ram:InvoiceCurrencyCode
BT-9Due datecbc:DueDateHS/ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime/udt:DateTimeString
BT-10Buyer reference (the Leitweg-ID for public buyers)cbc:BuyerReferenceHA/ram:BuyerReference
BT-24Specification identifiercbc:CustomizationIDrsm:ExchangedDocumentContext/ram:GuidelineSpecifiedDocumentContextParameter/ram:ID
BT-27Seller namecac:AccountingSupplierParty/cac:Party/cac:PartyLegalEntity/cbc:RegistrationNameHA/ram:SellerTradeParty/ram:Name
BT-31Seller VAT IDcac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[cac:TaxScheme/cbc:ID='VAT']/cbc:CompanyIDHA/ram:SellerTradeParty/ram:SpecifiedTaxRegistration/ram:ID[@schemeID='VA']
BT-44Buyer namecac:AccountingCustomerParty/cac:Party/cac:PartyLegalEntity/cbc:RegistrationNameHA/ram:BuyerTradeParty/ram:Name
BT-109Total without VATcac:LegalMonetaryTotal/cbc:TaxExclusiveAmountMS/ram:TaxBasisTotalAmount
BT-110Total VATcac:TaxTotal/cbc:TaxAmountMS/ram:TaxTotalAmount
BT-112Total with VATcac:LegalMonetaryTotal/cbc:TaxInclusiveAmountMS/ram:GrandTotalAmount
BT-115Amount duecac:LegalMonetaryTotal/cbc:PayableAmountMS/ram:DuePayableAmount
BT-129Invoiced quantity per linecac:InvoiceLine/cbc:InvoicedQuantityrsm:SupplyChainTradeTransaction/ram:IncludedSupplyChainTradeLineItem/ram:SpecifiedLineTradeDelivery/ram:BilledQuantity

How BT-10 is filled for public-sector buyers is covered in What is a Leitweg-ID?. If your code has to read both syntaxes, check the root element first and pick the paths from there. This Python example uses only the standard library and reads BT-10 and BT-112 from either variant:

import sys
import xml.etree.ElementTree as ET

NS = {
    "ubl": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
    "cac": "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2",
    "cbc": "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2",
    "rsm": "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100",
    "ram": "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100",
}

root = ET.parse(sys.argv[1]).getroot()
if root.tag == "{%s}Invoice" % NS["ubl"]:
    bt10 = root.findtext("cbc:BuyerReference", namespaces=NS)
    bt112 = root.findtext("cac:LegalMonetaryTotal/cbc:TaxInclusiveAmount", namespaces=NS)
elif root.tag == "{%s}CrossIndustryInvoice" % NS["rsm"]:
    tx = "rsm:SupplyChainTradeTransaction/"
    bt10 = root.findtext(tx + "ram:ApplicableHeaderTradeAgreement/ram:BuyerReference", namespaces=NS)
    bt112 = root.findtext(tx + "ram:ApplicableHeaderTradeSettlement/"
                          "ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:GrandTotalAmount", namespaces=NS)
else:
    sys.exit("Not an XRechnung: " + root.tag)
print("BT-10:", bt10, "| BT-112:", bt112)

The script works whatever prefix the file uses, because it looks elements up by namespace URI.

In what order is an XRechnung validated?

Validation runs in four stages. When one stage fails, the results of the later stages are often meaningless.

  1. Well-formedness. The file must be valid XML 1.0. An unescaped & in "Miller & Sons Ltd" makes it unreadable; write &amp; instead. See SCHEMA-001.
  2. XSD. The XSD schema of the syntax checks element names, order, mandatory elements and data types. A comma as decimal separator, a missing currencyID or broken Base64 content in an attachment fail here. See SCHEMA-003.
  3. EN 16931 Schematron. The standard's rules check mandatory fields (BR-…), calculations (BR-CO-…), code lists (BR-CL-…) and decimal places (BR-DEC-…), plus syntax-specific rules such as UBL-DT-01 (amounts with at most two decimals) or CII-DT-097 (date format). A typical hit is BR-CO-15: net plus VAT does not equal gross.
  4. KoSIT's XRechnung Schematron. The national BR-DE-… rules add to the standard, for example BR-DE-15 for a missing buyer reference BT-10. Some are "should" rules that only raise a warning; in version 3.0.2 this applies to BR-DE-17 (invoice type code) and BR-DE-21 (specification identifier).

The reference implementation for all four stages is the open-source KoSIT validator (opens in a new tab), written in Java, used together with the XRechnung validator configuration (opens in a new tab). The configuration bundles the XSD files and the Schematron rules compiled to XSLT. The validator picks a scenario based on the root element and BT-24. If none matches, it rejects the file without running the business rules at all.

java -jar validator-<version>-standalone.jar \
  -s validator-configuration-xrechnung/scenarios.xml \
  -r validator-configuration-xrechnung \
  -o reports -h \
  invoice.xml

The reports folder then contains an XML report whose verdict is accept or reject; -h also writes an HTML version. If you do not want to install Java, our e-invoice validator checks UBL and CII files against the official KoSIT rules and explains every message. All codes are listed under xrechnung validation errors, and the ten most common cases are covered in How to fix XRechnung validation errors.

What goes into BT-24 and BT-23?

BT-24 (cbc:CustomizationID or ram:GuidelineSpecifiedDocumentContextParameter/ram:ID) states which specification the file follows. For every 3.0.x release the identifier is urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0. If you use the Extension XRechnung, for example for sub-lines or XML attachments in construction, append #conformant#urn:xeinkauf.de:kosit:extension:xrechnung_3.0.

Older identifiers such as urn:xoev-de:kosit:standard:xrechnung_2.x are a common reason for rejection. BR-DE-21 only reports them as a warning, but the current validator configuration has no scenario for an expired version, so the file is rejected as a whole. The identifier is tied to the version; XRechnung 4.0 will use whatever identifier its final specification defines.

BT-23 (cbc:ProfileID or ram:BusinessProcessSpecifiedDocumentContextParameter/ram:ID) is optional in EN 16931 but mandatory in XRechnung 3.0.2: KoSIT's rules include the Peppol rule PEPPOL-EN16931-R001, "Business process MUST be provided". The usual value is urn:fdc:peppol.eu:2017:poacc:billing:01:1.0.

Which code lists and data formats apply?

  • Units of measure (BT-130) come from UN/ECE Recommendations 20 and 21, e.g. C62 (one), H87 (piece), HUR (hour), DAY (day), KGM (kilogram) and LS (lump sum).
  • VAT category codes (BT-118, BT-151) include S (standard rate), Z (zero rated), E (exempt), AE (reverse charge) and K (intra-community supply). The glossary entry VAT category code has the full list.
  • Invoice type codes (BT-3) come from UNTDID 1001. Under BR-DE-17, XRechnung expects 326, 380, 381, 384, 389, 875, 876 or 877; see invoice type code.
  • Currencies follow ISO 4217 (EUR), country codes ISO 3166-1 alpha-2 (DE).
  • Dates: UBL 2026-09-28, CII 20260928 with format="102".
  • Amounts use a dot as decimal separator and no thousands separator. Invoice amounts have at most two decimal places; unit prices may have more.
  • Encoding: UTF-8. The declaration in the prolog must match the actual bytes, otherwise "Straße" turns into "Straße" when the file is read.

What mistakes do developers make most often?

We reproduced each of the following cases with KoSIT validator 1.5.0 and the XRechnung 3.0.2 validator configuration.

MistakeWhat the report saysFix
Typo in a namespace URIno matching scenario, rejectedcopy the URI exactly from the table above
Element in the wrong positionXSD errorfollow the order defined in the schema
CII date 2026-09-28CII-DT-09720260928 with format="102"
CII date without formatBR-03, issue date missingadd the attribute
Comma as decimal separatorXSD error1785.00, not 1785,00
Three decimals in the amount dueBR-DEC-18, UBL-DT-01round to two places, recalculate totals
currencyID missing in UBLXSD error, BR-CL-03set the attribute on every amount
Unescaped & in a company namefile not well-formedwrite &amp; or let a serializer do it
Outdated identifier in BT-24BR-DE-21, no scenariouse the 3.0 identifier
cbc:ProfileID missingPEPPOL-EN16931-R001add BT-23
cbc:BuyerReference missingBR-DE-15enter the Leitweg-ID or another buyer reference

Most of these errors disappear once the file is written by an XML library that handles namespaces, escaping and encoding, rather than assembled by string concatenation.

Which tools help you read and check the XML?

For a quick look at the structure, the XML viewer opens any XML file as a collapsible tree. The xrechnung viewer renders UBL and CII invoices in readable form and validates them with the KoSIT rules. If you need a reference for your own output, create a UBL file with the xrechnung generator and compare it element by element. To test a parser, use the sample invoice and the deliberately broken test file. How attachments end up in the XML as Base64 is shown in XRechnung attachments, and the business side of producing a file is covered in how to create an XRechnung step by step.

Tags:XRechnungXMLUBLCIIXSDDevelopers

Tools for this article

Frequently asked questions

Is there an official XRechnung XSD?

No. XRechnung reuses the schemas of its two syntaxes: UBL 2.1 with UBL-Invoice-2.1.xsd and UBL-CreditNote-2.1.xsd, and UN/CEFACT CII D16B with CrossIndustryInvoice_100pD16B.xsd. KoSIT ships these files together with the Schematron rules in the validator-configuration-xrechnung package on GitHub. A schema check alone is not enough, because the business rules are only tested in the Schematron stage.

Is XRechnung UBL or CII?

Both. XRechnung is a semantic standard based on EN 16931 and may be expressed in UBL 2.1 or in UN/CEFACT CII D16B. Both variants carry the same identifier in BT-24 and run through the same business rules. UBL is common on the Peppol network, while CII is the XML part of every ZUGFeRD invoice. Your choice of syntax does not affect whether the invoice is valid.

What namespaces does a UBL XRechnung use?

A UBL XRechnung declares the document namespace urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 (CreditNote-2 for credit notes), plus CommonAggregateComponents-2 for cac elements and CommonBasicComponents-2 for cbc elements. The prefixes are arbitrary; only the URI counts. A single typo in a URI means the KoSIT validator finds no matching validation scenario and rejects the file.

What date format does XRechnung use?

It depends on the syntax. UBL uses the XML Schema date format YYYY-MM-DD, for example 2026-09-28 in cbc:IssueDate. CII writes the date without separators as 20260928 in udt:DateTimeString, with format code 102 in the format attribute. A hyphenated date in CII triggers CII-DT-097. Without the format attribute, the rules do not recognise the issue date at all and report BR-03.

What validation steps does an XRechnung have to pass?

Four stages. The file must be well-formed XML, match the XSD of its syntax, satisfy the EN 16931 Schematron rules (for example BR-CO-15: net plus VAT equals gross) and comply with KoSIT's XRechnung rules (for example BR-DE-15 for the buyer reference BT-10). The KoSIT validator runs all stages in order and writes a report that ends in accept or reject.

Topic hubMore on Developers & DataXML, JSON, Base64, CSV and timestamps: formats and tools for developers who work with e-invoices and business data.