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
| method | Produces | Notes |
|---|---|---|
xml | Well-formed XML | Default; no HTML shortcuts, self-closing empty elements |
html | HTML 4-style serialisation | Void elements unclosed, script content not escaped |
xhtml | XML serialisation of HTML | Well-formed, safe to parse with an XML parser |
text | No markup at all | Values 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-spaceremoves source whitespace-only text nodes and is usually required for clean output.disable-output-escapinginjects 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-prefixesandxsl: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.xmlEach 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 case | Why XSLT fits |
|---|---|
| DocBook, DITA, TEI publishing | One source, many outputs (HTML, print, EPUB) from the same tree |
| Enterprise data feeds | Fixed source schema, many consumer formats, validated at each hop |
| Sitemaps and feeds | Deterministic output from an index document, easy to validate |
| Configuration generation | One canonical config expanded into environment-specific variants |
| Reporting from XML exports | Grouping 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.
Related
Templates and apply-templates Validation with DTD and XSD
Last refreshed 2026-09-18.