Skip to main content

Formatting XML with Twig

· 2 min read
Stephan Hochdörfer
Head of IT Business Operations

Can we render the XML responses from a webservice our application interacts in a better readable way? This was the challenge I asked myself.

Our application connects to a third-party API, and we store the requests we send and the responses we receive for debugging purposes. The XML response does not contain any whitespaces or linebreaks, which makes it hard to read.

How to nicely format the string without writing custom XML parser logic? Luckily, PHP has us covered. We can instruct the DOMDocument to format the output like this:

$xmlResponse = '';

$dom = new \DOMDocument('1.0');
$dom->preserveWhiteSpace = true;
$dom->formatOutput = true;
$dom->loadXML($xmlResponse);

$formattedResponse = $dom->saveXML();

The $formattedResponse now contains a nicely formatted XML string. How do we render the formatted XML content via Twig? Writing a custom Twig extension felt like the best approach:

<?php

declare(strict_types=1);

namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;

class AppExtension extends AbstractExtension
{
public function getFilters(): array
{
return [
new TwigFilter('format_xml', [$this, 'formatXml']),
];
}

public function formatXml(string $xmlDoc): string
{
$dom = new \DOMDocument('1.0');
$dom->preserveWhiteSpace = true;
$dom->formatOutput = true;
$dom->loadXML($xmlDoc);

$formattedXmlDoc = $dom->saveXML();

return (false !== $formattedXmlDoc) ? $formattedXmlDoc : '';
}
}

To make Twig (and your Symfony application) aware of the custom Twig extension, the class needs to be registered as a service and tagged with twig.extension:

    App\Twig\AppExtension:
tags:
- { name: twig.extension }

In a Twig template, we can now use the format_xml filter as follows:

{{ data.xmlResponse|format_xml }}