This page provides quick start instructions for using the gobl.ubl library to convert between GOBL JSON and UBL XML formats. It covers installation, basic conversion patterns in both directions, and command-line tool usage.
For detailed information about the conversion system architecture, see Conversion System. For information about specific document components like parties, line items, and taxes, see Document Components.
Add the library to your Go project using:
The package requires Go 1.24.4 or later (as specified in go.mod3) and depends on the core GOBL library (github.com/invopop/gobl v0.308.0).
Sources: README.md1-8 go.mod1-6 go.sum33-34
Install the command-line tool directly from source:
This installs the gobl.ubl executable to your $GOPATH/bin directory. Ensure this directory is in your system PATH.
Sources: README.md114-118
The library provides bidirectional conversion between GOBL and UBL formats through four primary API functions defined in the ubl package:
Core Conversion Functions:
Conversion Direction Decision Matrix:
| Starting With | Need | Use Function | Defined In | Returns |
|---|---|---|---|---|
| GOBL Envelope | UBL struct | ubl.ConvertInvoice() | ubl.go | *ubl.Invoice |
| UBL struct | XML bytes | ubl.Bytes() | ubl.go | []byte |
| UBL XML bytes | UBL struct | ubl.Parse() | ubl.go | *ubl.Invoice |
| UBL struct | GOBL Envelope | (*Invoice).Convert() | invoice_from.go | *gobl.Envelope |
Sources: README.md10-110
Converting a GOBL Envelope to UBL XML involves three steps: reading the envelope, converting to UBL structure, and marshaling to XML bytes.
Conversion Pipeline:
The complete pattern is demonstrated in README.md25-56 Key steps:
*gobl.Envelopeubl.ConvertInvoice(env) to get *ubl.Invoice
ubl.Convert() which extracts the invoice from the envelopeContextEN16931)ensureAddons() functionublInvoice() orchestrator functionubl.Bytes(doc) to marshal to XML with XML declaration headerThe ubl.ConvertInvoice() function is a convenience wrapper that:
*gobl.Envelope directlybill.Invoice documentubl.Convert() for the actual conversion*ubl.Invoice ready for serializationThe default conversion uses ContextEN16931. To use a different UBL profile (Peppol, XRechnung, etc.), pass a context option using the WithContext() function:
Available Context Constants (defined in context.go):
| Constant | Standard | Addon Requirement | ProfileID |
|---|---|---|---|
ContextEN16931 | European EN 16931 | en16931-v2017 | urn:cen.eu:en16931:2017 |
ContextPeppol | Peppol BIS Billing 3.0 | en16931-v2017 | urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 |
ContextPeppolSelfBilled | Peppol Self-Billed | en16931-v2017 | urn:fdc:peppol.eu:2017:poacc:selfbilling:01:1.0 |
ContextXRechnung | German XRechnung | xrechnung-v3 | urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0 |
ContextPeppolFranceCIUS | French CIUS | ctc-flow2-v1 | urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0#conformant#urn:fdc:peppol.eu:2017:poacc:billing:3.0:extended:urn:fdc:aife.economie.gouv.fr:billing:1.0 |
ContextPeppolFranceExtended | French Extended | facturx-v1 | Custom Output ID |
Each context influences:
For more details on contexts and how they affect conversion, see Context and Profile System.
Sources: README.md58-62 examples_test.go56-68
Converting UBL XML to GOBL format involves parsing the XML and converting the resulting structure to a GOBL Envelope.
Parsing Pipeline:
The complete pattern is demonstrated in README.md66-109 Key steps:
ubl.Parse(inData) with XML bytes
extractRootNamespace() to distinguish Invoice from CreditNotexmlctx.Unmarshal() for namespace-aware XML parsing*ubl.Invoice (both Invoice and CreditNote implement the same interface)inv.Convert() to get *gobl.Envelope
FindContext() to detect context from CustomizationID/ProfileIDgoblParty() functiongoblAddLines() functionbill.Invoice in a gobl.Envelopeinv.ExtractBinaryAttachments() for embedded binary filesUBL documents may contain embedded binary attachments in AdditionalDocumentReference elements with EmbeddedDocumentBinaryObject nodes (Base64-encoded). Extract them separately using the ExtractBinaryAttachments() method:
Binary Attachment Structure:
The extraction method:
AdditionalDocumentReference elementsAttachment.EmbeddedDocumentBinaryObject (Base64 data)BinaryAttachment structs with Filename and Data fieldsSources: README.md101-102
The gobl.ubl CLI tool provides automatic format detection and bidirectional conversion without writing code.
CLI Detection Logic (cmd/gobl.ubl/convert.go):
Convert any supported file by providing input and optional output paths:
Command Structure:
The convert command is implemented using the Cobra CLI framework:
convertCmd with usage, description, and argument validationrunConvert() handles the actual conversion logicjson.Valid() from the standard library to detect JSON vs XMLThe implementation in cmd/gobl.ubl/convert.go:
gobl.Envelope → calls ubl.Convert() → calls ubl.Bytes() → writes XMLubl.Parse() → calls invoice.Convert() → marshals JSON → writes JSONSources: README.md112-129
The repository includes comprehensive example documents for testing and reference:
| Directory | Purpose | Format |
|---|---|---|
test/data/convert/ | GOBL → UBL conversion examples | Input: .json, Output: .xml |
test/data/parse/ | UBL → GOBL parsing examples | Input: .xml, Output: .json |
Examples are organized by UBL profile in separate subdirectories:
Example Directory Structure:
| Subdirectory | Context Constant | Standard | Test Function |
|---|---|---|---|
en16931/ | ContextEN16931 | European EN 16931 standard | TestConvertToInvoice |
peppol/ | ContextPeppol | Peppol BIS Billing 3.0 | TestConvertToInvoice |
peppol-self-billed/ | ContextPeppolSelfBilled | Peppol self-billed variant | TestConvertToInvoice |
xrechnung/ | ContextXRechnung | German XRechnung | TestConvertToInvoice |
france-cius/ | ContextPeppolFranceCIUS | French CIUS | TestConvertToInvoice |
france-extended/ | ContextPeppolFranceExtended | French extended | TestConvertToInvoice |
Test Automation in examples_test.go:
The test suite uses filepath.Glob() to automatically discover and process all example files in each context directory:
Test file categories include:
Each test:
out/ subdirectoryFor detailed example analysis, see Example Documents.
Sources: examples_test.go42-122 examples_test.go124-220
The library includes a comprehensive test framework for validating conversions:
Command-Line Flags (defined in examples_test.go):
| Flag Variable | Purpose | Usage Example |
|---|---|---|
updateOut | Regenerate expected output files in out/ directories | go test -update ./... |
validate | Run Phive gRPC validation on generated XML documents | go test -validate ./... |
Test Framework Validation (examples_test.go):
The test framework validates:
Test Helper Functions:
testInvoiceFrom(): Converts GOBL JSON to UBL InvoicetestInvoiceFromContext(): Converts with specific contextloadTestEnvelope(): Loads and validates GOBL envelopetestParseInvoice(): Parses UBL XML to GOBL envelopeValidateXML(): Validates XML against XSD schema using libxml2For details on the test framework, see Test Framework.
Sources: examples_test.go36-41 examples_test.go42-122 examples_test.go368-381
Be aware of these limitations when converting between formats:
| UBL Field | BG/BT Code | Impact | Mitigation |
|---|---|---|---|
AdditionalReferencedDocument | BG-24 | Not supported in GOBL | Lost in conversion |
Multiple InvoicePeriod | BG-14 | Only first period used | Additional periods ignored |
ProfileID | BT-23 | Not stored in GOBL | Detected but not preserved |
CustomizationID | BT-24 | Not stored in GOBL | Detected but not preserved |
AccountingCost | BT-19, BT-133 | No GOBL equivalent | Added as notes |
TaxTotal and enriched into lines/chargesBaseQuantity when converting from UBLFor complete data transformation rules, see Data Transformation Rules.
Sources: README.md141-150
After getting started with basic conversions, explore these topics:
For development and contribution information, see Development.
Sources: README.md1-158
Refresh this wiki