XmlService Class

XmlService is the entry point of the library: it encodes, decodes and validates XML documents in one place. It gives the work to three components, that can also be used alone.

Service Structure

  1. XmlEncoder: Converts PHP arrays to XML documents.
  2. XmlDecoder: Converts XML documents to PHP arrays.
  3. XmlValidator: Validates XML documents against XSD schemas.

XmlServiceInterface is the three interfaces together (XmlEncoderInterface, XmlDecoderInterface and XmlValidatorInterface).

Basic Usage

use Derafu\Xml\Service\XmlEncoder;
use Derafu\Xml\Service\XmlDecoder;
use Derafu\Xml\Service\XmlValidator;
use Derafu\Xml\Service\XmlService;

// Initialize the components.
$encoder = new XmlEncoder();
$decoder = new XmlDecoder();
$validator = new XmlValidator();

// Create the service.
$xmlService = new XmlService($encoder, $decoder, $validator);

In an application with the Symfony container, resources/config/xml-services.yaml of the library registers the interfaces with their classes.

Encoding (Array to XML)

The encode() method converts a PHP array to an XML document (see Array Structure):

$data = [
    'invoice' => [
        '@attributes' => [
            'id' => '12345',
            'date' => '2025-03-05'
        ],
        'client' => [
            'name' => 'Acme Corporation',
            'tax_id' => '123456789'
        ],
        'items' => [
            'item' => [
                [
                    '@attributes' => ['id' => '1'],
                    'description' => 'Product A',
                    'quantity' => '2',
                    'price' => '19.99'
                ],
                [
                    '@attributes' => ['id' => '2'],
                    'description' => 'Product B',
                    'quantity' => '1',
                    'price' => '29.99'
                ]
            ]
        ],
        'total' => '69.97'
    ]
];

$xmlDocument = $xmlService->encode($data);

$xmlDocument->saveXml() gives:

<?xml version="1.0" encoding="UTF-8"?>
<invoice id="12345" date="2025-03-05">
  <client>
    <name>Acme Corporation</name>
    <tax_id>123456789</tax_id>
  </client>
  <items>
    <item id="1">
      <description>Product A</description>
      <quantity>2</quantity>
      <price>19.99</price>
    </item>
    <item id="2">
      <description>Product B</description>
      <quantity>1</quantity>
      <price>29.99</price>
    </item>
  </items>
  <total>69.97</total>
</invoice>

The encoding of the XML is UTF-8. To have another one: $xmlDocument->setEncoding('ISO-8859-1').

An array that can not be an XML throws an XmlEncoderException (see Exceptions).

Using Namespaces

The namespaces are declared in the @attributes of the element, with xmlns for the default one and xmlns:prefix for the others. The names of the elements have the prefix:

$data = [
    'inv:invoice' => [
        '@attributes' => [
            'xmlns:inv' => 'http://example.com/invoice',
            'id' => '12345',
        ],
        'inv:client' => 'Acme Corporation',
    ],
];

$xmlDocument = $xmlService->encode($data);

This generates:

<?xml version="1.0" encoding="UTF-8"?>
<inv:invoice xmlns:inv="http://example.com/invoice" id="12345">
  <inv:client>Acme Corporation</inv:client>
</inv:invoice>

Decoding (XML to Array)

The decode() method converts an XML document to a PHP array:

// Assuming $xmlDocument is a Derafu\Xml\XmlDocument instance.
$array = $xmlService->decode($xmlDocument);

// Or starting from a DOMElement of the document.
$element = $xmlDocument->getDocumentElement();
$array = $xmlService->decode($element);

A document without document element is an empty array.

The array has what the XML has: attributes and the namespaces that the elements declare in @attributes, comments in @comment, and text exactly as it is. See Array Structure and Round Trip and Fidelity.

Handling Repeated Elements

Elements with the same name are collected into a list:

<root>
  <item>Value 1</item>
  <item>Value 2</item>
  <item>Value 3</item>
</root>

Becomes:

[
    'root' => [
        'item' => [
            'Value 1',
            'Value 2',
            'Value 3'
        ]
    ]
]

An element that appears once is its value, not a list of one.

Validation

The validate() method checks an XML document against an XSD schema:

use Derafu\Xml\Exception\XmlException;

try {
    $xmlService->validate($xmlDocument, '/path/to/schema.xsd');
    echo "XML is valid!";
} catch (XmlException $e) {
    echo "Validation failed: " . $e->getMessage();

    // The errors of libxml, as XmlError.
    foreach ($e->getErrors() as $error) {
        echo "- $error\n";
    }

    // The document that was validated.
    $document = $e->getXmlDocument();
}

The message has all the errors:

The XML validation failed using the schema schema.xsd: Line 1, column 0: Element 'wrong': No matching global declaration available for the validation root.

The errors are explained and translated from their code (see Exceptions), and the namespace of the names, that libxml writes between braces ({urn:example}), is taken out.

Schema Auto-Detection

If the XML document has an xsi:schemaLocation attribute, the schema path can be omitted: the schema is the path that comes after the namespace.

// XML with xsi:schemaLocation="http://example.com/ns /path/to/schema.xsd"
try {
    $xmlService->validate($xmlDocument); // Will use /path/to/schema.xsd
} catch (XmlException $e) {
    // Handle validation error.
}

The path has to be one of a file that exists. If the document does not have xsi:schemaLocation, or the path does not exist, an XmlException is thrown.

Integration Example

This example shows a typical workflow:

// Initialize the service.
$xmlService = new XmlService(new XmlEncoder(), new XmlDecoder(), new XmlValidator());

// Create XML from array.
$data = ['root' => ['element' => 'value']];
$xmlDocument = $xmlService->encode($data);

// Save to a file.
file_put_contents('document.xml', $xmlDocument->saveXml());

// Load from a file.
$loadedXml = new \Derafu\Xml\XmlDocument();
$loadedXml->loadXml(file_get_contents('document.xml'));

try {
    // Validate.
    $xmlService->validate($loadedXml, '/path/to/schema.xsd');

    // Convert back to array.
    $array = $xmlService->decode($loadedXml);

    // Process the data.
    // ...

} catch (\Derafu\Xml\Exception\XmlException $e) {
    // Handle validation errors.
}
On this page

Last updated on 30/10/2026 by Anonymous