Sponsored

XSLT Reference

for-each-pair()

XSLT 3.0 higher-order function

Applies a binary function to corresponding items from two sequences, returning the concatenated results.

Syntax
for-each-pair(seq1, seq2, function)

Description

for-each-pair() simultaneously iterates over two sequences, applying a binary function to each pair of corresponding items (first item from seq1 with first from seq2, second with second, etc.). Processing stops when the shorter sequence is exhausted.

Parameters

ParameterTypeRequiredDescription
seq1item()*YesThe first sequence.
seq2item()*YesThe second sequence.
functionfunction(item(), item()) as item()*YesA binary function applied to each item pair.

Return value

item()* — concatenated results of applying the function to each pair; length equals min(count(seq1), count(seq2)).

Examples

Zipping two sequences into key-value pairs

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="/">
    <xsl:variable name="keys"   select="('name', 'age', 'city')"/>
    <xsl:variable name="values" select="('Alice', '30', 'Paris')"/>
    <record>
      <xsl:sequence select="for-each-pair($keys, $values,
        function($k, $v) { element {$k} {$v} }
      )"/>
    </record>
  </xsl:template>
</xsl:stylesheet>

Output:

<record>
  <name>Alice</name>
  <age>30</age>
  <city>Paris</city>
</record>

Computing pairwise differences

Input XML:

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <actual>10 20 35 50</actual>
  <expected>12 18 35 48</expected>
</data>

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="/data">
    <xsl:variable name="actual"   select="for-each(tokenize(actual),   xs:integer#1)"/>
    <xsl:variable name="expected" select="for-each(tokenize(expected), xs:integer#1)"/>
    <diffs>
      <xsl:for-each select="for-each-pair($actual, $expected,
        function($a, $e) { $a - $e })">
        <diff><xsl:value-of select="."/></diff>
      </xsl:for-each>
    </diffs>
  </xsl:template>
</xsl:stylesheet>

Output:

<diffs>
  <diff>-2</diff>
  <diff>2</diff>
  <diff>0</diff>
  <diff>2</diff>
</diffs>

Notes

  • When sequences have different lengths, the result length equals the shorter sequence — excess items from the longer sequence are ignored.
  • The function must accept exactly two arguments.
  • For array-based pair processing, use array:for-each-pair().

See also