XSLT - XSLT <xsl:on-empty> for Default Output Generation

<xsl:on-empty> is an XSLT 3.0 instruction used when you want to provide fallback content when a sequence constructor produces an empty sequence. In simple terms, it allows an XSLT stylesheet to say: "If this processing produces something, use it; otherwise, generate this default content."

This is particularly useful when transforming XML documents where some elements or values may be missing. Instead of writing separate conditional logic with xsl:if or xsl:choose, <xsl:on-empty> provides a concise way to specify what should happen when the expected result is empty.

1. Why <xsl:on-empty> Is Needed

Consider an XML document containing employee information:

<employee>
    <name>John</name>
    <department>Finance</department>
</employee>

Suppose an XSLT transformation tries to retrieve:

employee/email

Because the <email> element does not exist, the XPath expression returns an empty sequence.

Without <xsl:on-empty>, the transformation may produce no output for that part of the result.

With <xsl:on-empty>, you can provide a default value such as:

Email address not available

This makes the output more complete and easier for users to understand.

2. Basic Syntax

The general structure is:

<xsl:on-empty>
    default content
</xsl:on-empty>

It is normally used as part of a sequence constructor.

For example:

<xsl:value-of select="employee/email"/>
<xsl:on-empty>
    <xsl:text>Email address not available</xsl:text>
</xsl:on-empty>

The important idea is that the instructions before <xsl:on-empty> produce the primary result. If that result is empty, the instructions inside <xsl:on-empty> provide the alternative result.

3. Basic Example

Consider this XML:

<employee>
    <name>John</name>
    <email>[email protected]</email>
</employee>

An XSLT stylesheet could contain:

<xsl:template match="employee">
    <result>
        <xsl:value-of select="email"/>
        <xsl:on-empty>
            <xsl:text>Email address not available</xsl:text>
        </xsl:on-empty>
    </result>
</xsl:template>

Since the email element exists, the result contains:

<result>[email protected]</result>

The fallback content is not used.

Now consider:

<employee>
    <name>John</name>
</employee>

There is no email element. Therefore, the primary expression produces an empty sequence, and the fallback content is used:

<result>Email address not available</result>

4. <xsl:on-empty> Works with Empty Sequences

The key concept behind this instruction is the empty sequence.

XPath expressions frequently return sequences. A sequence can contain one item, several items, or no items.

For example:

name

might return:

John

But:

email

could return nothing if the <email> element is absent.

In XPath terminology, this is an empty sequence:

()

<xsl:on-empty> is designed specifically to react to this situation.

For example:

<xsl:value-of select="email"/>
<xsl:on-empty>
    <xsl:text>No email found</xsl:text>
</xsl:on-empty>

If email returns an empty sequence, the fallback is generated.

5. Difference Between Empty and Non-Empty Values

It is important to distinguish between an empty sequence and other values.

Suppose the XML contains:

<email/>

The email element exists, although it has no text content.

This situation is different from:

<employee>
    <name>John</name>
</employee>

where the email element does not exist at all.

<xsl:on-empty> is primarily concerned with whether the sequence being processed contains items. Therefore, developers should understand the difference between:

()

and an existing node whose string value happens to be empty.

This distinction becomes particularly important when designing reliable XML transformations.

6. Providing Default Elements

The fallback does not have to be simple text. You can generate XML elements.

For example:

<xsl:template match="employee">
    <contact>
        <xsl:sequence select="email"/>
        <xsl:on-empty>
            <status>Not Provided</status>
        </xsl:on-empty>
    </contact>
</xsl:template>

If an email exists, the normal result is produced.

If the email is absent, the transformation can produce:

<contact>
    <status>Not Provided</status>
</contact>

This makes <xsl:on-empty> useful for constructing structured XML output.

7. Using <xsl:on-empty> with Conditional Processing

The fallback can also contain other XSLT instructions.

For example:

<xsl:on-empty>
    <xsl:choose>
        <xsl:when test="@type = 'temporary'">
            <xsl:text>Temporary employee</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text>Information unavailable</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
</xsl:on-empty>

This allows the fallback itself to contain more sophisticated processing.

Therefore, <xsl:on-empty> does not necessarily mean that the fallback must be a fixed string.

8. Difference Between <xsl:on-empty> and xsl:if

A common alternative is:

<xsl:if test="email">
    <xsl:value-of select="email"/>
</xsl:if>

This checks whether the email element exists.

If you need a default value, you might write:

<xsl:choose>
    <xsl:when test="email">
        <xsl:value-of select="email"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>Email not available</xsl:text>
    </xsl:otherwise>
</xsl:choose>

<xsl:on-empty> provides another approach that focuses directly on whether the generated sequence is empty.

This can make transformations more expressive when the important requirement is:

Use the normal result if available; otherwise use a fallback.

9. Difference Between <xsl:on-empty> and xsl:choose

xsl:choose is a general-purpose conditional instruction.

For example:

<xsl:choose>
    <xsl:when test="email">
        <xsl:value-of select="email"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>Email not available</xsl:text>
    </xsl:otherwise>
</xsl:choose>

This explicitly evaluates a condition.

<xsl:on-empty> approaches the problem differently. It lets the normal processing happen and specifies what to generate if that processing results in an empty sequence.

Therefore:

xsl:choose
    = Make a decision based on a condition.

xsl:on-empty
    = Provide fallback content when the result is empty.

This distinction makes <xsl:on-empty> particularly useful in sequence-oriented XSLT 3.0 programming.

10. Multiple Items and Sequence Processing

XSLT is designed around sequences rather than simply individual values.

Suppose an XML document contains:

<employees>
    <employee>
        <name>John</name>
    </employee>
    <employee>
        <name>Mary</name>
    </employee>
</employees>

An XPath expression such as:

employees/employee/name

returns multiple nodes.

Because the result is not empty, the fallback is not required.

The important principle is:

One or more items → normal result
No items → fallback result

This makes <xsl:on-empty> useful when processing collections of nodes as well as individual values.

11. Practical Example

Consider an XML product catalog:

<product>
    <name>Laptop</name>
    <price>75000</price>
</product>

Suppose the stylesheet expects a product description.

A transformation can use:

<xsl:template match="product">
    <product-details>
        <name>
            <xsl:value-of select="name"/>
        </name>

        <description>
            <xsl:value-of select="description"/>
            <xsl:on-empty>
                <xsl:text>Description not available</xsl:text>
            </xsl:on-empty>
        </description>
    </product-details>
</xsl:template>

Since the source does not contain a <description> element, the generated result can provide a meaningful default instead of leaving the output unexpectedly empty.

12. Advantages of <xsl:on-empty>

One major advantage is conciseness. Instead of creating a separate condition simply to detect an empty result, the fallback can be associated directly with the sequence constructor.

It also improves readability. Someone examining the stylesheet can immediately see both the normal processing and the fallback behavior.

Another advantage is better handling of optional XML data. Real-world XML documents often contain missing fields, optional elements, or incomplete records. <xsl:on-empty> provides a convenient mechanism for dealing with these situations.

It can also help produce consistent output. Rather than leaving fields blank when source information is missing, a transformation can generate meaningful default content.

13. Common Use Cases

<xsl:on-empty> can be useful in several scenarios.

Missing Customer Information

If a customer has no phone number:

Phone: Not provided

Missing Product Description

If a product has no description:

Description: Not available

Missing Address

If an address is absent:

Address information unavailable

Empty Search Results

When an XPath expression finds no matching records, the stylesheet can generate an appropriate message.

Optional XML Sections

When transforming documents where certain sections are optional, a fallback can be generated when the section produces no result.

14. Important Point About XSLT Version

<xsl:on-empty> is associated with XSLT 3.0.

Therefore, it should not be treated as a feature available in older XSLT versions such as XSLT 1.0.

When using XSLT 3.0 features, the stylesheet should normally specify the appropriate version:

<xsl:stylesheet version="3.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

The actual support also depends on the XSLT processor being used.

15. <xsl:on-empty> vs XPath Defaulting

Another way to provide a default is through XPath expressions.

For example, the XPath expression:

(email, 'Email not available')[1]

can select the email if available and otherwise use the default string.

This approach is useful when the fallback is simply a value.

<xsl:on-empty> becomes more attractive when the fallback involves sequence-construction instructions or more structured output.

For example, a fallback can contain:

<xsl:on-empty>
    <status>
        <xsl:text>Information unavailable</xsl:text>
    </status>
</xsl:on-empty>

This makes it more flexible for constructing output.

16. Example with a Complete XSLT Stylesheet

Source XML:

<employees>
    <employee>
        <name>John</name>
        <email>[email protected]</email>
    </employee>

    <employee>
        <name>Mary</name>
    </employee>
</employees>

XSLT:

<xsl:stylesheet version="3.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <employees>
            <xsl:apply-templates select="employees/employee"/>
        </employees>
    </xsl:template>

    <xsl:template match="employee">
        <employee>
            <name>
                <xsl:value-of select="name"/>
            </name>

            <email>
                <xsl:value-of select="email"/>
                <xsl:on-empty>
                    <xsl:text>Email not available</xsl:text>
                </xsl:on-empty>
            </email>
        </employee>
    </xsl:template>

</xsl:stylesheet>

The resulting output conceptually becomes:

<employees>
    <employee>
        <name>John</name>
        <email>[email protected]</email>
    </employee>
    <employee>
        <name>Mary</name>
        <email>Email not available</email>
    </employee>
</employees>

The first employee has an email address, so the normal result is generated. The second employee has no email, so the fallback is used.

17. Key Points to Remember

<xsl:on-empty> is an XSLT 3.0 instruction for fallback processing.

Its main purpose is to provide output when the preceding sequence constructor produces an empty sequence.

It is especially useful when working with optional or missing XML data.

It differs from xsl:if and xsl:choose because it focuses on the result of sequence construction, rather than requiring an explicit boolean condition.

The fallback can contain text, XML elements, or other XSLT instructions.

It is particularly valuable when creating reliable transformations where missing source data should result in meaningful default output rather than an unexpectedly empty result.

In short, the fundamental idea is:

Normal processing produces a result
            |
            v
      Is the result empty?
        /          \
      No            Yes
      |              |
Keep result     Use xsl:on-empty
                     |
                     v
               Generate fallback

This makes <xsl:on-empty> a useful XSLT 3.0 feature for building transformations that gracefully handle missing or optional data.