Sponsored

XSLT Reference

filter()

XSLT 3.0 higher-order function

Returns items from a sequence for which a predicate function returns true, discarding all others.

Syntax
filter(sequence, predicate)

Description

filter() applies a predicate function to each item in a sequence and returns only those items for which the predicate returns true. It is the functional equivalent of an XPath predicate expression but accepts a function item, enabling reusable and composable filtering logic.

Parameters

ParameterTypeRequiredDescription
sequenceitem()*YesThe sequence to filter.
predicatefunction(item()) as xs:booleanYesA function of arity 1 that returns true to keep the item, false to discard it.

Return value

item()* — the subsequence of items for which the predicate returned true, in document order.

Examples

Filtering even numbers

Stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">

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

  <xsl:template match="/">
    <result>
      <xsl:variable name="numbers" select="1 to 10"/>
      <xsl:variable name="evens" select="filter($numbers, function($n) { $n mod 2 = 0 })"/>
      <xsl:for-each select="$evens">
        <num><xsl:value-of select="."/></num>
      </xsl:for-each>
    </result>
  </xsl:template>
</xsl:stylesheet>

Output:

<result>
  <num>2</num>
  <num>4</num>
  <num>6</num>
  <num>8</num>
  <num>10</num>
</result>

Filtering XML nodes by attribute value

Input XML:

<?xml version="1.0" encoding="UTF-8"?>
<orders>
  <order id="1" status="shipped" amount="99.00"/>
  <order id="2" status="pending" amount="45.00"/>
  <order id="3" status="shipped" amount="120.00"/>
  <order id="4" status="cancelled" amount="30.00"/>
</orders>

Stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">

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

  <xsl:template match="/orders">
    <xsl:variable name="shipped"
      select="filter(order, function($o) { $o/@status = 'shipped' })"/>
    <shipped-orders total="{sum($shipped/@amount)}">
      <xsl:copy-of select="$shipped"/>
    </shipped-orders>
  </xsl:template>
</xsl:stylesheet>

Output:

<shipped-orders total="219">
  <order id="1" status="shipped" amount="99.00"/>
  <order id="3" status="shipped" amount="120.00"/>
</shipped-orders>

Notes

  • The predicate function must return xs:boolean; effective boolean value (EBV) is not applied automatically.
  • filter() preserves the original sequence order.
  • Composable with for-each(), fold-left(), and sort() for pipeline-style data transformation.
  • For arrays, use array:filter() which operates on array members rather than a flat sequence.

See also