Re: [xsl] [XSLT Streaming] I xsl:iterate over airport primary records; how do I get the following sibling airport continuation record?

Subject: Re: [xsl] [XSLT Streaming] I xsl:iterate over airport primary records; how do I get the following sibling airport continuation record?
From: "Martin Honnen martin.honnen@xxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 31 Jan 2025 19:40:35 -0000
On 31/01/2025 20:25, Roger L Costello costello@xxxxxxxxx wrote:
Hi Folks,

I am stream-processing a huge air navigation file that contains, among other
things, airport primary records:

<ARINC> ... <record> <ARINC_424-18_4_1_7_1_Airport_Primary_Records> data about an airport </ARINC_424-18_4_1_7_1_Airport_Primary_Records> </record> ... </ARINC>

In my program, I iterate over the airport primary records:

<xsl:iterate
select="ARINC/record/ARINC_424-18_4_1_7_1_Airport_Primary_Records">
     process an airport
</xsl:iterate>

Some--not all--airport primary records have a continuation record, which
immediately follows--is the first following sibling--the airport primary
record:

<ARINC> ... <record> <ARINC_424-18_4_1_7_1_Airport_Primary_Records> data about an airport </ARINC_424-18_4_1_7_1_Airport_Primary_Records> </record> <record>

<ARINC_424-18_4_1_7_3_Airport_Flight_Planning_Continuation_Records>
additional data about the airport

</ARINC_424-18_4_1_7_3_Airport_Flight_Planning_Continuation_Records>
         </record>
         ...
</ARINC>

Within the xsl:iterate loop, I tried to obtain the following continuation
record and store it into a variable:

<xsl:iterate
select="ARINC/record/ARINC_424-18_4_1_7_1_Airport_Primary_Records">
<xsl:variable name="flt-pln-cont"
select="copy-of(../following-sibling::record[1]/ARINC_424-18_4_1_7_3_Airport_
Flight_Planning_Continuation_Records)"/>
     process the airport and its continuation data
</xsl:iterate>

When I run my program, I get this error message:

Static error at xsl:source-document on line 10 column 47 of
create-airports.xsl:
XTSE3430 The body of the xsl:source-document instruction is not
streamable
* Cannot use the following-sibling axis when context posture is CLIMBING
(line 16)
* Expression
parent::(element()|document-node())/following-sibling::record[1] requires
sorting nodes into document order

What is the correct way to do this?


With streamings, you process each node once in a forwards only way.


It is not clear to me why you process e.g.
ARINC/record/ARINC_424-18_4_1_7_1_Airport_Primary_Records if a "record"
element can also contain e.g.
ARINC_424-18_4_1_7_3_Airport_Flight_Planning_Continuation_Records, your
outer xsl:iterate would already have skipped the
ARINC_424-18_4_1_7_3_Airport_Flight_Planning_Continuation_Records
elements if it only looks for ARINC_424-18_4_1_7_1_Airport_Primary_Records.

As for ways to solve this, it is not clear how large a "record" element
is, e.g. if you perhaps could just use

B <xsl:iterate select="ARINC/record!copy-of()">

B B B B B  <xsl:param name="previous-record" as="element(record)?"
select="()"/>

B B B B  <xsl:next-iteration>
B B B B B B  <xsl:with-param name="previous-record" select="."/>

B B B </xsl:next-iteration>

B </xsl:iterate>


There are also capturing accumulators (a Saxon extension in XSLT 3 but streaming is only implemented by Saxon anyway) that can help store nodes.

Or streaming with e.g.

B B  <xsl:for-each-groups select="ARINC/record!copy-of()"
group-starting-with="record[ARINC_424-18_4_1_7_1_Airport_Primary_Records]">

None of that is pure streaming, of course, but unless you buffer the
"ARINC_424-18_4_1_7_1_Airport_Primary_Records" data in a map I don't
think there is a way to look back with streamed processing.

Current Thread