PHPackages                             xterr/php-ubl - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. xterr/php-ubl

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

xterr/php-ubl
=============

UBL 2.x XSD-to-PHP 8.4+

1.2.0(3mo ago)01392MITPHPPHP ^8.2CI passing

Since Apr 10Pushed 3mo agoCompare

[ Source](https://github.com/xterr/php-ubl)[ Packagist](https://packagist.org/packages/xterr/php-ubl)[ RSS](/packages/xterr-php-ubl/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (6)Dependencies (2)Versions (7)Used By (2)

PHP UBL
=======

[](#php-ubl)

[![PHP](https://camo.githubusercontent.com/ccaa43fc634d348cffccb1d8db7b55d9f17c5d46944bc99a15c3c982724b387d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)[![CI](https://github.com/xterr/php-ubl/actions/workflows/ci.yml/badge.svg)](https://github.com/xterr/php-ubl/actions/workflows/ci.yml)[![Packagist Version](https://camo.githubusercontent.com/acb1fcb68e7937037ba5b5e3caabc7d64411b7721ca0003a46aeeefb3aaecfce/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f78746572722f7068702d75626c)](https://packagist.org/packages/xterr/php-ubl)[![PHPStan Level 8](https://camo.githubusercontent.com/ff3c7f8c8667ce643f47e74532748f673482a5f95d7d4269f925f2eebbe5117e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c253230382d627269676874677265656e)](https://phpstan.org/)

Attribute-driven XML serializer/deserializer for UBL 2.x documents in PHP 8.2+.

Map PHP classes to UBL XML elements using native PHP attributes, then serialize and deserialize without writing a single line of DOM code. Built-in XXE prevention, namespace management, and `DateTimeImmutable` support out of the box.

Features
--------

[](#features)

- **PHP 8 Attributes** - Declarative XML mapping via `#[XmlRoot]`, `#[XmlElement]`, `#[XmlAttribute]`, `#[XmlValue]`, `#[XmlType]`, `#[XmlAny]`
- **Full UBL 2.x Namespace Support** - CBC, CAC, EXT, SIG, SAC, SBC, DS, CCTS, UDT, QDT
- **Serialization** - PHP objects to well-formed UBL XML with automatic namespace declarations
- **Deserialization** - UBL XML to typed PHP objects with recursive hydration
- **XXE Prevention** - DOCTYPE stripping and entity rejection on both serialize and deserialize paths
- **DateTimeImmutable** - Configurable date/time format support for date elements and values
- **Choice Groups** - XSD `xs:choice` constraint validation via `#[ChoiceGroupConstraint]`
- **Raw XML Passthrough** - `#[XmlAny]` for extension elements and untyped XML fragments
- **Metadata Caching** - Reflection-based metadata is built once and cached per class
- **Zero Dependencies** - Only requires `ext-dom` and `ext-libxml`

Installation
------------

[](#installation)

```
composer require xterr/php-ubl
```

**Requirements:**

- PHP 8.2 or higher
- `ext-dom`
- `ext-libxml`

Quick Start
-----------

[](#quick-start)

### Define a UBL document class

[](#define-a-ubl-document-class)

```
use Xterr\UBL\Xml\Mapping\XmlRoot;
use Xterr\UBL\Xml\Mapping\XmlElement;
use Xterr\UBL\Xml\Mapping\XmlAttribute;
use Xterr\UBL\Xml\Mapping\XmlValue;
use Xterr\UBL\Xml\Mapping\XmlNamespace;

#[XmlRoot(localName: 'Invoice', namespace: 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2')]
class Invoice
{
    #[XmlElement(name: 'ID', namespace: XmlNamespace::CBC)]
    private ?string $id = null;

    #[XmlElement(name: 'IssueDate', namespace: XmlNamespace::CBC, format: 'Y-m-d')]
    private ?\DateTimeImmutable $issueDate = null;

    #[XmlElement(name: 'InvoiceTypeCode', namespace: XmlNamespace::CBC)]
    private ?string $invoiceTypeCode = null;

    // Getters and setters...
    public function getId(): ?string { return $this->id; }
    public function setId(?string $id): void { $this->id = $id; }
    public function getIssueDate(): ?\DateTimeImmutable { return $this->issueDate; }
    public function setIssueDate(?\DateTimeImmutable $issueDate): void { $this->issueDate = $issueDate; }
    public function getInvoiceTypeCode(): ?string { return $this->invoiceTypeCode; }
    public function setInvoiceTypeCode(?string $invoiceTypeCode): void { $this->invoiceTypeCode = $invoiceTypeCode; }
}
```

### Serialize to XML

[](#serialize-to-xml)

```
use Xterr\UBL\Xml\XmlSerializer;

$invoice = new Invoice();
$invoice->setId('INV-001');
$invoice->setIssueDate(new \DateTimeImmutable('2025-01-15'));
$invoice->setInvoiceTypeCode('380');

$serializer = new XmlSerializer();
$xml = $serializer->serialize($invoice);
```

### Deserialize from XML

[](#deserialize-from-xml)

```
use Xterr\UBL\Xml\XmlDeserializer;

$deserializer = new XmlDeserializer();
$invoice = $deserializer->deserialize($xml, Invoice::class);

echo $invoice->getId(); // "INV-001"
```

Mapping Attributes
------------------

[](#mapping-attributes)

AttributeTargetPurpose`#[XmlRoot]`ClassMarks class as a document root element with local name and namespace`#[XmlType]`ClassDeclares the XSD complex type name and namespace`#[XmlElement]`PropertyMaps property to an XML child element`#[XmlAttribute]`PropertyMaps property to an XML attribute`#[XmlValue]`PropertyMaps property to the text content of the element`#[XmlAny]`PropertyCaptures unmapped child elements as raw XML fragments### `#[XmlElement]` options

[](#xmlelement-options)

```
#[XmlElement(
    name: 'ID',                         // XML element local name
    namespace: XmlNamespace::CBC,       // XML namespace URI
    type: MyType::class,                // Inner type for array properties
    format: 'Y-m-d',                   // Date format (for DateTimeImmutable)
    required: true,                     // Whether the element is required
    choiceGroup: 'address',            // XSD choice group name
)]
```

UBL Namespaces
--------------

[](#ubl-namespaces)

All standard UBL 2.x namespaces are available as constants on `XmlNamespace`:

ConstantPrefixNamespace URI`CBC``cbc``urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2``CAC``cac``urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2``EXT``ext``urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2``SIG``sig``urn:oasis:names:specification:ubl:schema:xsd:CommonSignatureComponents-2``SAC``sac``urn:oasis:names:specification:ubl:schema:xsd:SignatureAggregateComponents-2``SBC``sbc``urn:oasis:names:specification:ubl:schema:xsd:SignatureBasicComponents-2``DS``ds``http://www.w3.org/2000/09/xmldsig#``CCTS``ccts``urn:un:unece:uncefact:data:specification:CoreComponentTypeSchemaModule:2``UDT``udt``urn:oasis:names:specification:ubl:schema:xsd:UnqualifiedDataTypes-2``QDT``qdt``urn:oasis:names:specification:ubl:schema:xsd:QualifiedDataTypes-2`Working with Collections
------------------------

[](#working-with-collections)

For array properties, define the inner type via the `type` parameter or a `@var` docblock:

```
/** @var list */
#[XmlElement(name: 'InvoiceLine', namespace: XmlNamespace::CAC, type: InvoiceLine::class)]
private array $invoiceLines = [];

public function getInvoiceLines(): array { return $this->invoiceLines; }
public function addToInvoiceLines(InvoiceLine $line): void { $this->invoiceLines[] = $line; }
```

The serializer iterates the array and writes one element per item. The deserializer calls `addTo{PropertyName}()` for each occurrence.

Error Handling
--------------

[](#error-handling)

All exceptions implement `Xterr\UBL\Exception\ExceptionInterface`:

ExceptionWhen`SerializationException`Object is not a root document, or DOM serialization fails`DeserializationException`XML parse error, XXE detected, size limit exceeded, or date parsing fails`SchemaParseException`XSD schema parsing fails`GeneratorException`Code generation failsDevelopment
-----------

[](#development)

```
# Install dependencies
composer install

# Run tests
composer test

# Run static analysis
composer analyze
```

### CI

[](#ci)

Tests run on PHP 8.2, 8.3, and 8.4 via GitHub Actions. Tagged releases are automatically notified to Packagist.

License
-------

[](#license)

[MIT](LICENSE) - Copyright (c) 2026 Ceana Razvan

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance80

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

6

Last Release

105d ago

PHP version history (2 changes)1.0.0PHP ^8.1

1.0.1PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/d9526b453abaa7d569fdacdf58cb0f55aa8d889f68f5b622344a28b37eb6c17d?d=identicon)[razvanceana](/maintainers/razvanceana)

---

Top Contributors

[![xterr](https://avatars.githubusercontent.com/u/619509?v=4)](https://github.com/xterr "xterr (8 commits)")

---

Tags

xmlxsdublpeppole-invoicingoasisprocurementespd

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/xterr-php-ubl/health.svg)

```
[![Health](https://phpackages.com/badges/xterr-php-ubl/health.svg)](https://phpackages.com/packages/xterr-php-ubl)
```

###  Alternatives

[veewee/xml

XML without worries

1837.0M39](/packages/veewee-xml)[easybill/e-invoicing

A package to read and create EN16931 e-invoices or CIUS like: XRechnung, ZUGFeRD etc.

14158.3k](/packages/easybill-e-invoicing)[goetas-webservices/xsd2php

Convert XSD (XML Schema) definitions into PHP classes and JMS metadata

2391.7M45](/packages/goetas-webservices-xsd2php)[goetas-webservices/xsd2php-runtime

Convert XSD (XML Schema) definitions into PHP classes

4912.6M45](/packages/goetas-webservices-xsd2php-runtime)[goetas-webservices/xsd-reader

Read any XML Schema (XSD) programmatically with PHP

625.2M22](/packages/goetas-webservices-xsd-reader)[goetas-webservices/wsdl-reader

Pure PHP WSDL parser

10351.5k7](/packages/goetas-webservices-wsdl-reader)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
