在目前在 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>
我还没有对此进行测试(这是四天假期前夕的深夜......)但如果您有兴趣采用这种方法,我将很乐意提供帮助。XSLT 3.0 仍然是一个草案规范并且相当流畅。它的重点是使用流式方法解决此类问题,该方法使用有界内存处理非常大的文档。Saxon-EE 9.4 实现了规范的快照。