現在 Saxon-EE に実装されている XSLT 3.0 (ドラフト) では、この問題を解決するストリーミング変換を次のように記述できます。
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:map="http://www.w3.org/2005/xpath-functions/map">
<xsl:mode streamable="yes"/>
<xsl:template match="/">
<xsl:iterate select="Document/Data">
<xsl:param name="map" select="map{}"/>
<xsl:choose>
<xsl:when test="@category='1'">
<xsl:next-iteration>
<xsl:with-param name="map" select="map:put($map, string(@Id), string(@Body))"/>
</xsl:next-iteration>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Cat1 Body: ',
$map(@CorrespondingCategoryId), 'Cat2 Body', @Body"/>
</xsl:otherwise>
</xsl:choose>
</xsl:iterate>
</xsl:template>
私はこれをテストしていません (4 連休の前夜の深夜です...) が、このアプローチを追求することに興味がある場合は、喜んでお手伝いします。XSLT 3.0 はまだドラフト仕様であり、かなり流動的です。その焦点は、制限されたメモリを使用して非常に大きなドキュメントを処理するストリーミング アプローチを使用して、このような問題を解決することにあります。Saxon-EE 9.4 では、仕様のスナップショットが実装されています。