1
0
mirror of https://github.com/alexandrev/xslt-lab.git synced 2026-09-18 19:43:16 +00:00
Files
xslt-lab/site/content/xslt/functions/xsl-where-populated.md
T
alexandrev-tibco 53e90ef86e feat(blog): complete XSLT/XPath reference — 229 function pages
Full coverage of XSLT 1.0, 2.0 and 3.0 elements and XPath functions:
- 59 XSLT elements (xsl:stylesheet → xsl:use-accumulators)
- 170 XPath functions (1.0 node/string/numeric/boolean, 2.0 sequence/
  date/QName/string, 3.0 HOF/map/array/JSON/streaming)
Each page: description, parameters table, return value, 2 runnable
Saxon examples with input XML + stylesheet + output, notes, cross-links.
xsltCompletions.js: all 229 entries now have blogSlug for hover links.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 09:28:05 +02:00

4.0 KiB

title, description, date, version, versionLabel, category, syntax, tags
title description date version versionLabel category syntax tags
xsl:where-populated Suppresses the entire wrapper element, including its start and end tags, when its content sequence constructor produces no nodes. 2026-04-18T00:00:00Z 3.0 XSLT 3.0 element <xsl:where-populated>...</xsl:where-populated>
xslt
reference
xslt3

Description

xsl:where-populated wraps an element constructor and suppresses the entire wrapper — open tag, close tag, and everything between — if the content would be empty. This differs from xsl:on-empty, which generates fallback content, and from xsl:on-non-empty, which conditionally prepends content. xsl:where-populated is about wholesale suppression of a wrapping element.

The most frequent problem it solves is the "empty wrapper" antipattern: you want to emit <errors>...</errors> only when there are errors, but you cannot know in advance whether any errors exist. The naive approach tests with a variable or count(). With xsl:where-populated you write the element constructor normally and let the processor decide at runtime whether to emit it.

xsl:where-populated must contain exactly one element constructor (a literal result element or xsl:element) as its direct child. The processor evaluates the children of that element; if the result is empty, neither the inner element nor xsl:where-populated emits anything. If the result is non-empty, the inner element is written to the output as usual.

This element is particularly powerful in streaming stylesheets, where you cannot look ahead.

Attributes

xsl:where-populated has no element-specific attributes. It must contain a single element-constructing child.

Examples

Suppress an empty errors wrapper

Input XML:

<?xml version="1.0" encoding="UTF-8"?>
<batch>
  <job id="1" status="ok"/>
  <job id="2" status="ok"/>
</batch>

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:template match="/batch">
    <report>
      <xsl:where-populated>
        <errors>
          <xsl:apply-templates select="job[@status != 'ok']"/>
        </errors>
      </xsl:where-populated>
      <summary>
        <xsl:value-of select="count(job)"/> jobs processed.
      </summary>
    </report>
  </xsl:template>

  <xsl:template match="job">
    <error id="{@id}"><xsl:value-of select="@status"/></error>
  </xsl:template>
</xsl:stylesheet>

Output (no errors element because no failed jobs):

<report>
  <summary>2 jobs processed.</summary>
</report>

Combining with xsl:apply-templates in a streaming context

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 streamable="yes" on-no-match="shallow-skip"/>

  <xsl:template match="/catalog">
    <catalog>
      <xsl:where-populated>
        <featured>
          <xsl:apply-templates select="product[@featured='true']"/>
        </featured>
      </xsl:where-populated>
      <xsl:where-populated>
        <discontinued>
          <xsl:apply-templates select="product[@discontinued='true']"/>
        </discontinued>
      </xsl:where-populated>
    </catalog>
  </xsl:template>

  <xsl:template match="product">
    <item id="{@id}"><xsl:value-of select="name"/></item>
  </xsl:template>
</xsl:stylesheet>

Notes

  • The direct child of xsl:where-populated must be a single element constructor. Wrapping multiple elements requires an outer xsl:element or restructuring.
  • Text nodes, comments, and processing instructions produced by the inner content are all considered "populated".
  • xsl:where-populated is streamable.
  • It cannot be used to suppress non-element output (e.g. a text node or attribute) — use xsl:on-empty for that pattern instead.

See also