Output methods and real use cases

Choosing between xml, html and text output, controlling encoding and whitespace, and the jobs XSLT still does well.

Controlling the output

methodProducesNotes
xmlWell-formed XMLDefault; no HTML shortcuts, self-closing empty elements
htmlHTML 4-style serialisationVoid elements unclosed, script content not escaped
xhtmlXML serialisation of HTMLWell-formed, safe to parse with an XML parser
textNo markup at allValues only — CSV, plain logs, one-line output
<xsl:output method="xml"
            version="1.0"
            encoding="UTF-8"
            indent="yes"
            omit-xml-declaration="no"/>

<xsl:output method="text"/>
<xsl:strip-space elements="*"/>   <!-- ignore source indentation -->
<xsl:preserve-space elements="pre code"/>
  • indent="yes" only affects element-only content; mixed content is left alone.
  • xsl:strip-space removes source whitespace-only text nodes and is usually required for clean output.
  • disable-output-escaping injects raw markup and is a common XSS vector — avoid it when the content is untrusted.
  • Namespaces in the output can be controlled with exclude-result-prefixes and xsl:namespace-alias.
⚠️
Never combine disable-output-escaping with user-supplied content. It bypasses the escaping that makes XML and HTML output safe, and it is not honoured by all processors anyway.

Chaining transformations

# stage 1: normalise, stage 2: render - a common publishing pipeline
xsltproc normalise.xsl raw.xml | xsltproc render.xsl - > page.html

# render to print via XSL-FO, then to PDF
xsltproc fo.xsl catalog.xml > catalog.fo
fop -fo catalog.fo -pdf catalog.pdf

# generate a sitemap from a content index
xsltproc sitemap.xsl index.xml > sitemap.xml && xmllint --noout sitemap.xml

Each stage keeps XML as its interface, so a change in the normalisation rules never touches the presentation stylesheet. That separation is the reason XSLT survives in publishing pipelines.

Where XSLT still earns its place

Use caseWhy XSLT fits
DocBook, DITA, TEI publishingOne source, many outputs (HTML, print, EPUB) from the same tree
Enterprise data feedsFixed source schema, many consumer formats, validated at each hop
Sitemaps and feedsDeterministic output from an index document, easy to validate
Configuration generationOne canonical config expanded into environment-specific variants
Reporting from XML exportsGrouping and sorting without loading data into a database
  • Use XSLT when the input and output are both documents and the mapping is structural.
  • Use a general-purpose language when the logic needs state, network calls, or complex validation — XSLT is deliberately side-effect free.
  • Profile before optimising: most slow stylesheets are slow because of repeated // searches that a key would fix.
  • Keep stylesheets under version control and test them against a fixture document; a broken template often fails silently.

FAQ

Should I use XSLT for a JSON API?
Probably not. XSLT is strongest when both sides are documents. For JSON in and JSON out, a general-purpose language with a template engine is simpler to test and debug.
How do I test a stylesheet?
Keep a small fixture XML plus its expected output in the repository and run the transformation in CI. Diffing output catches the silent failures that unit-testing templates cannot.

Templates and apply-templates Validation with DTD and XSD

Last refreshed 2026-09-18.