Streaming with xsl:merge

Saxon (since 9.6) allows several streamed inputs to be merged using the new XSLT 3.0 xsl:merge instruction. For this to work, there are a number of rules to follow (these are slightly different from the rules in the draft XSLT 3.0 specification):

  1. Streaming must be requested by specifying streamable="yes" on the xsl:merge-source element.

  2. When streaming is requested, the for-each-stream attribute of xsl:merge-source must be present, and must be a single string.

  3. The select attribute on the xsl:merge-source element must take the form of a motionless pattern.

For each node selected by the select expression, Saxon takes an implicit snapshot (in the sense of the XSLT 3.0 fn:snapshot() function). The merge keys are evaluated in relation to this snapshot, and it is this snapshot that is presented within the xsl:merge-action construct as the result of the fn:current-merge-group() function.

Here is an example of streamed merging of two log files:

<xsl:merge> <xsl:merge-source streamable="yes" for-each-stream="'log-file-1.xml'" select="events/event"> <xsl:merge-key select="xs:dateTime(@timestamp)"/> </xsl:merge-source> <xsl:merge-source streamable="yes" for-each-stream="'log-file-2.xml'" select="log/day/record"> <xsl:merge-key select="dateTime(../@date, time)"/> </xsl:merge-source> <xsl:merge-action> <group> <xsl:copy-of select="current-merge-group()" /> </group> </xsl:merge-action> </xsl:merge>