J. Nicholas
J. Nicholas

Reputation: 105

Storing data for use during streaming

I am attempting to stream an XML file using XSLT3. It has a number of tags that constitute "reusable" data that will need to be used during the processing of the repeating data (where streaming shines).

<Root>
    <ReusableData1>
        <ReferenceData id="1">
            <a/>
            <b/>
        </ReferenceData>
        <ReferenceData id="2">
            <a/>
            <b/>
        </ReferenceData>
    </ReusableData1>
    <RepeatingData>
        <RefId>1</RefId>
    </RepeatingData>
    <RepeatingData>
        <RefId>2</RefId>
    </RepeatingData>
 ...
</Root>

I cannot just copy-of the ReusableData into a variable due to the single downward selection restriction. I imagine accumulators come in to play here, but I can't make sense of them. The examples I see uses maps with primitive types, I need to store at least partial node-sets, as the reference data contains additional elements.

Upvotes: 0

Views: 64

Answers (2)

Michael Kay
Michael Kay

Reputation: 163458

It should be as simple as

<xsl:accumulator name="reusable-data" as="element(ReusableData1)">
  <xsl:accumulator-rule match="ReusableData1" select="." saxon:capture="yes"/>
</xsl:accumulator>

and then later

<xsl:value-of select="accumulator-after('reusable-data')/ReferenceData[@id='1']/a"/>

Upvotes: 1

Martin Honnen
Martin Honnen

Reputation: 167696

With Saxon, there is the extension attribute saxon:capture, see https://www.saxonica.com/html/documentation/extensions/attributes/capture.html, that should help:

If a large document has a short header section containing metadata, you can capture a copy of the header in an accumulator, and the header then becomes available throughout the rest of the document processing using the accumulator-after() function

Upvotes: 1

Related Questions