UBL vs CII: which invoice XML syntax should you choose?
Two XML syntaxes can represent an EN16931-compliant electronic invoice: UBL 2.1 and UN/CEFACT Cross Industry Invoice (CII). Both are correct. Both are accepted by EN16931. And both are structurally different enough that code written for one cannot parse the other without a separate implementation.
If you are building an invoice pipeline in Europe in 2026, you will probably encounter both. Here is what you need to know to pick the right one and handle the other.
What they have in common
Both UBL and CII are serializations of the same semantic model: EN16931. A seller name is a seller name. A VAT amount is a VAT amount. The business terms (BT) and business groups (BG) are identical across both syntaxes.
EN 16931-2 defines the official mapping from each BT to its XML path in both syntaxes. The document is free from CEN/TC 434 and is the authoritative reference when you need to implement both.
Both formats are based on international standards and are accepted by EN16931 validators. Both produce machine-readable structured invoices.
How they differ structurally
The differences are significant and pervasive. Element names, namespace prefixes, nesting structures, and attribute conventions are all different.
Seller name (BT-27)
UBL 2.1:
<cac:AccountingSupplierParty>
<cac:Party>
<cac:PartyName>
<cbc:Name>Acme GmbH</cbc:Name>
</cac:PartyName>
</cac:Party>
</cac:AccountingSupplierParty>
CII:
<rsm:SupplyChainTradeTransaction>
<ram:SellerTradeParty>
<ram:Name>Acme GmbH</ram:Name>
</ram:SellerTradeParty>
</rsm:SupplyChainTradeTransaction>
UBL uses deep nesting with aggregate (cac:) and basic (cbc:) component namespaces. CII is flatter, with ram: (Reusable Aggregate Module) and rsm: (Reusable Schema Module) namespaces.
Invoice line amount (BT-131)
UBL 2.1:
<cac:InvoiceLine>
<cbc:LineExtensionAmount currencyID="EUR">250.00</cbc:LineExtensionAmount>
</cac:InvoiceLine>
CII:
<ram:IncludedSupplyChainTradeLineItem>
<ram:SpecifiedLineTradeSettlement>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>250.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
Currency codes in CII are element attributes in some places and absent in others (with currency declared at header level). UBL is more consistent: currencyID appears on every monetary amount element.
Root element and namespaces
UBL 2.1 uses three namespaces:
<Invoice xmlns="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">
CII uses three different namespaces:
<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">
There is no overlap between the two namespace sets. A parser targeting one format cannot process the other.
Which format is mandated where
The choice is rarely yours to make. The format is determined by the target country, the delivery channel, and the compliance framework.
| Format | Mandated by |
|---|---|
| UBL 2.1 | Peppol BIS Billing 3.0 (network transport) |
| CII | Factur-X, ZUGFeRD, XRechnung (both CII and UBL accepted) |
| CII or UBL | France (Portail Public de Facturation: both accepted) |
Peppol BIS Billing 3.0 is UBL only. If you are transmitting over the Peppol network, you must produce UBL.
Factur-X and ZUGFeRD are CII. The factur-x.xml attachment inside a PDF/A-3 is always CII.
XRechnung accepts both CII and UBL, but CII (CrossIndustryInvoice) is more commonly tested by German government portal validators.
Conversion between formats
There is no lossless automatic conversion between UBL and CII. The semantic content is identical, but:
- Some fields map to attributes in one format and elements in the other
- The nesting depth differs, affecting how you read sequential items like invoice lines
- Currency code placement differs between formats (some CII implementations assume header currency applies to all lines)
- Date formats differ: UBL uses
YYYY-MM-DD, CII usesYYYYMMDDwith aformat="102"attribute
Conversion is possible but requires a dedicated mapping layer. Using XSLT is common; the OpenPEPPOL community provides reference mappings.
Performance and tooling
UBL is more widely supported in .NET and Java libraries. OASIS UBL has been around since 2006 and most enterprise XML tooling has explicit support for it.
CII is less common in European developer tooling outside France and Germany. Parser libraries exist but tend to be more specialized.
Saxon HE handles Schematron validation for both. The pre-compiled XSLT files from the Peppol BIS GitHub releases include separate XSLT files:
peppol-en16931-ubl.xsl (for UBL invoices)
peppol-en16931-cii.xsl (for CII invoices)
Run each against the appropriate input format.
Which one to implement first
For most developers starting a new European invoice integration in 2026, UBL is the better starting point:
- Peppol network transport requires UBL
- Most EU countries accept UBL on national portals
- .NET and Java tooling is more mature
- The UBL specification is more consistent in attribute placement
If you operate in France or Germany specifically, CII becomes necessary for Factur-X and ZUGFeRD. That is a second implementation layer, not a replacement.
For archival purposes, PDF/A-3 with embedded CII is the standard. Most pipelines that transmit Peppol UBL over the network also generate a Factur-X CII PDF for the buyer’s archive. The two serve different functions and coexist.
A note on validation
Regardless of which syntax you use, validate against the correct profile’s Schematron rules. An invoice that is valid UBL may fail Peppol BIS 3.0 rules if it is missing mandatory Peppol-specific elements. An invoice that is valid CII may fail the Factur-X EN 16931 profile if optional fields required by that profile are absent.
The deeper problem is that most pipelines need both. A Peppol delivery requires UBL. The buyer’s archive requires a Factur-X PDF with embedded CII. Maintaining two independent XML generation paths, two validation passes, and two sets of Schematron rule files doubles the surface area for correctness bugs.
SealDoc generates both from the same input. A single API call with your invoice data produces the UBL document for Peppol transmission and the PDF/A-3 with embedded CII for the buyer’s archive. Schematron validation runs against both outputs before either is returned. You do not need to maintain either XML generation path or track Peppol BIS releases.
For checking existing files, the SealDoc public validator accepts both UBL and CII and reports failures by BT number and business rule code. Useful for diagnosing documents received from trading partners or for calibrating a third-party invoice export against EN16931 requirements.