- How do I install simonschaufi/pretty-xml in a Laravel project?
- Install it with Composer by running composer require simonschaufi/pretty-xml. The package is framework-agnostic, so there is no service provider or config file to register in Laravel. Just import the PrettyXml\Formatter class wherever you need to format or minify XML strings.
- Can I configure the indent size and indent character when pretty printing XML?
- Yes. The Formatter class exposes setIndentSize() to change the number of spaces per level and setIndentCharacter() to swap spaces for tabs or any other character. This is the main reason to use pretty-xml over DOMDocument, which does not let you configure indent distance directly. Call the setters before format() on your XML string.
- How do I minify XML and optionally keep comments with pretty-xml?
- Use the minify() method on the Formatter instance. Pass true as the second argument to preserve comments, for example $formatter->minify($xml, true). Without that flag, comments are stripped along with the whitespace between elements, which is usually what you want for API responses.
- Which PHP and Laravel versions does pretty-xml support?
- Version 3.1.1 requires PHP 8.1 or newer and depends only on PHP core extensions, so it works with any modern Laravel release including Laravel 9, 10 and 11. Because it is a plain PHP library with no framework coupling, Laravel version upgrades do not affect it. Pin to ^3.1.1 to guarantee the idempotency fix.
- Is pretty-xml idempotent when the same XML is formatted more than once?
- Yes, as of version 3.1.1. That release fixed a bug where repeated formatting of text nodes could produce progressively different output, so format-then-format now converges to a stable result. This matters for stacked middleware, cache-then-reformat flows and queued post-processing. Always require ^3.1.1 rather than ^3.0.
- How do I use pretty-xml inside Laravel middleware to format XML responses?
- The Formatter is stateless and side-effect-free, so you can call format() or minify() on the response content inside a middleware after the response is generated. Because formatting is now idempotent, a response can safely pass through several formatting layers without drifting. Replace hardcoded DOMDocument::saveXML() calls with the Formatter to keep this concern out of your domain code.
- What is the performance impact of pretty-printing XML in production?
- Pretty-printing adds roughly 1 to 5 milliseconds per request for large XML payloads, depending on size and depth. For high-traffic endpoints, default to minify() in production and reserve prettyPrint() for debugging or local environments, or cache the minified output in Redis or the Laravel cache. Benchmark with payloads over 1MB before rolling it out broadly.
- How do I test XML output formatted with pretty-xml in PHPUnit?
- Use assertXmlStringEqualsXmlString() to compare the semantic structure of the generated XML, and add a regression test asserting that formatting twice equals formatting once. That double-format check locks in the idempotency guarantee introduced in 3.1.1. The Formatter is easy to mock or call directly in unit tests since it has no dependencies.
- What are the alternatives to pretty-xml for formatting XML in PHP?
- The built-in DOMDocument with saveXML() can pretty print, but it offers no control over indent distance and no idempotency guarantee without custom code. Spatie\ArrayToXml handles array-to-XML conversion rather than formatting existing XML, so it solves a different problem. For a focused pretty printer and minifier, pretty-xml remains the lightest option.
- Does pretty-xml handle namespaces, doctype declarations, or whitespace-sensitive XML like SOAP envelopes?
- The 3.1.1 fix targets text-node convergence and does not claim to solve structural edge cases such as namespaces or doctype declarations, which may still need custom handling. Whitespace-sensitive XML, including some SOAP envelopes, can be altered by pretty printing, so test against representative payloads. When formatting requirements are strict, minify() is usually the safer choice.