Sponsored

XSLT Reference

xsl:on-empty

XSLT 3.0 element

Generates fallback content when the sibling sequence constructor produces no nodes, enabling clean empty-state handling without extra variables.

Syntax
<xsl:on-empty>...</xsl:on-empty>

Description

xsl:on-empty solves a recurring XSLT problem: how do you output something meaningful when a query returns no results? Before XSLT 3.0 you had to bind the result to a variable, test whether the variable was empty, and then branch with xsl:choose. xsl:on-empty eliminates this boilerplate by acting as an inline fallback within the same sequence of instructions.

The element is evaluated after all preceding siblings in the same sequence constructor have been evaluated. If those siblings produced no nodes at all — not even whitespace-only text nodes — then the content of xsl:on-empty is output instead. If any node was produced, xsl:on-empty is silently skipped.

This is particularly useful in streaming contexts where you cannot look ahead to know whether content exists before committing to write a wrapper element. Paired with xsl:on-non-empty and xsl:where-populated, these three elements form a trio for conditional-content control in XSLT 3.0.

Attributes

xsl:on-empty has no element-specific attributes. It contains a sequence constructor.

Examples

Empty list fallback

Input XML:

<?xml version="1.0" encoding="UTF-8"?>
<library>
  <books>
    <!-- no book elements here -->
  </books>
</library>

Stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes"/>

  <xsl:template match="/library">
    <ul>
      <xsl:apply-templates select="books/book"/>
      <xsl:on-empty>
        <li class="empty">No books available.</li>
      </xsl:on-empty>
    </ul>
  </xsl:template>

  <xsl:template match="book">
    <li><xsl:value-of select="title"/></li>
  </xsl:template>
</xsl:stylesheet>

Output:

<ul>
  <li class="empty">No books available.</li>
</ul>

Conditional section with multiple content sources

Stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="/report">
    <report>
      <warnings>
        <xsl:apply-templates select="item[@severity='high']"/>
        <xsl:apply-templates select="item[@severity='critical']"/>
        <xsl:on-empty>
          <message>All clear — no warnings.</message>
        </xsl:on-empty>
      </warnings>
    </report>
  </xsl:template>

  <xsl:template match="item">
    <warning level="{@severity}"><xsl:value-of select="."/></warning>
  </xsl:template>
</xsl:stylesheet>

Notes

  • xsl:on-empty looks only at nodes produced by preceding siblings in the same sequence constructor, not at the final result tree. Whitespace-only text nodes do count as content.
  • It is safe to use in streaming mode because it works with already-processed content.
  • Only one xsl:on-empty should appear per sequence constructor; having multiple is allowed but only the first may ever fire.
  • Do not confuse with testing count(nodes) = 0xsl:on-empty avoids needing a variable binding altogether.

See also