XSLT guide
Debug XSLT output, escaping, and serialization
Separate the XSLT result tree from its serialized bytes and fix wrong output methods, encodings, escaped markup, and indentation assumptions.
8 min read · Updated 2026-08-21
The short answer
First inspect the result tree the transformation constructs, then inspect how the processor serializes that tree. xsl:output controls method, encoding, declaration, and indentation only when serialization occurs. Create elements with literal result elements or xsl:element instead of assembling markup as text, and avoid disable-output-escaping because it is serialization-dependent, fragile across pipelines, and can turn data into active markup.Choose the output method intentionally
The XML, HTML, text, JSON, and adaptive output methods serialize different data models under different rules. A stylesheet returning a DOM or sequence through an API may not serialize at all, so xsl:output can appear to do nothing.
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/">
<report><xsl:copy-of select="/*/*"/></report>
</xsl:template>
</xsl:stylesheet>Build nodes instead of markup strings
xsl:value-of creates text, so angle brackets in its value are escaped when XML or HTML is serialized. That is correct: the value is data, not a request to inject nodes. Use literal result elements, xsl:element, xsl:attribute, or xsl:copy-of to create structure.
- Treat escaped markup as a data-model question before changing the serializer.
- Avoid disable-output-escaping in reusable stylesheets and multi-stage pipelines.
- Do not rely on indentation for mixed-content documents.
- Compare bytes only after declaring and honoring the intended encoding.
Test trees and bytes separately
Assert node names, namespaces, attributes, and text on the transformation result before serializing it. Then serialize with the production processor and assert the output method, declaration, encoding, and any canonical form required by a downstream signature or byte comparison.
If the result feeds XML Signature, never pretty-print and assume semantic equivalence is enough. The signature library must canonicalize the referenced node using the declared algorithm.
Prove the fix
- Format the resultSeparate human-readable layout from the result tree's actual structure.
- Inspect canonical bytesUnderstand how namespace and attribute normalization affect signing.
- Trace template dispatchFix missing nodes before investigating their serialization.
Related guides
- XSLT match vs select: know which expression runs whenDistinguish template patterns from XPath selections, trace modes and priority, and fix stylesheets that choose nodes but run the wrong rule.
- Make XSLT match a default namespaceFix XSLT templates that never fire when source elements use a default namespace, with patterns that work across XSLT versions.
- Verify an XML Signature safelySeparate reference digest validation, SignatureValue verification, key trust, and application meaning so a valid XML signature protects the intended data.
Get started
Bring order to the XML your team can't afford to ignore.
Create a free account and get a private workspace to search, validate, diff, and monitor your XML feeds, sitemaps, schemas, and vendor integrations.