Re: [xsl] Question on XSLT streaming and accumulation of values

Subject: Re: [xsl] Question on XSLT streaming and accumulation of values
From: "Felix Sasaki felix@xxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 16 Oct 2017 05:54:05 -0000
Thank you very much for your feedback, Michael and Martin.

I have two other questions. First, does it matter wheter
accumulator-before() or accumulator-after()? I assume not because the
metadata values do not change before or after processing a given loop2
element.

Second, I have an additional requirement to process metadata that appears
at the end of the document:

<GROUP>
        <group-meta1>metainfo-group-1</group-meta1>
        <TRANSACTION>
            <transaction-meta>
                <transaction-meta1>metainfo-transaction-1</transaction-meta1
>
            </transaction-meta>
            <loop1>...</loop1>
            <loop2>to be done1</loop2>
            <loop2>to be done2</loop2>
        </TRANSACTION>
<document-end-metadata><foo/><bar/></document-end-metadata>
    </GROUP>

For each loop2, I want to copy not the values but the whole XML tree
of document-end-metadata.
Currently I am achieving this by doing two streams. a) go through the
document and gather the document-end-metadata subtree to be put into a
variable b) process the loop2 elements and add a copy of the variable into
the loop2 specific output.

Since this requirement means copying a sub tree and not values, I assume
there is no way to achieve this with accumulators or xsl:iterate, or other
approaches?


Regards,

Felix



2017-10-15 21:43 GMT+02:00 Michael Kay mike@xxxxxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>:

>
> On 15 Oct 2017, at 20:26, Felix Sasaki felix@xxxxxxxxxxxxxx <
> xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> Accidentally I sent the below mail to the wrong mail address, and
> inbetween found a solution to the issue: using for the accumulator
> match="group-meta1/text()" select="string(.)"
>
>
> That's the solution I was going to suggest until I saw that you'd already
> come up with it.
>
> In case there are other solutions, I am eager to learn about them .
>
>
> Another possibility would be to process the children of GROUP using
> xsl:iterate: something like
>
> <xsl:template match="GROUP">
>   <xsl:iterate select="*">
>     <xsl:param name="group-meta-1" select="()"/>
>     <xsl:choose>
>      <xsl:when test="self::group-meta-1">
>        <xsl:next-iteration>
>          <xsl:with-param name="group-meta-1" select="string(.)"/>
>        </
>     </
>     <xsl:otherwise>
>       <xsl:apply-templates select=".">
>         <xsl:with-param name="group-meta-1" select="$group-meta-1"
> tunnel="yes"/>
>       </
>     </
>   </
> </
>
>
>
>
> I have an XML input of the following structure
>
>     <GROUP>
>         <group-meta1>metainfo-group-1</group-meta1>
>         <TRANSACTION>
>             <transaction-meta>
>                 <transaction-meta1>metainfo-tr
> ansaction-1</transaction-meta1>
>             </transaction-meta>
>             <loop1>...</loop1>
>             <loop2>to be done1</loop2>
>             <loop2>to be done2</loop2>
>         </TRANSACTION>
>     </GROUP>
>
> I want to process all loop2 elements with XSLT 3.0 streaming. For each
> loop2 element, there should be a uri generated which is defined as follows:
>
>     value of group-meta1 + "/" + value of group-meta2 + "/" + loop2 number
>
> That is for the loop2 with the value "to be done" the uri
>
>     /metainfo-group-1/metainfo-transaction-1/1.xml
>
> And for the second loop2 the uri
>
>     /metainfo-group-1/metainfo-transaction-1/2.xml
>
>
> Is this possible with streaming? I tried templates gathering the
> metainformation, but that works only if I use copy-of to gather the
> meta-information, e.g. in this template:
>
> <xsl:template mode="process-loop2" match="GROUP">
>         <xsl:variable name="current-group" select="copy-of(.)" />
>         <xsl:apply-templates mode="process-loop2"
> select="$current-group/*">
>             <xsl:with-param name="group-meta1"
> select="$current-group/group-meta1"/>
>         </xsl:apply-templates>
>     </xsl:template>
>
>
> The issue with this solution is that I need to keep the whole GROUP
> element in memory, via copy-of(), and a group already can be several
> gigabyte. With saxon, that leads to an out-of-memory error.
>
> I guess the problem is that I want to do two things within one stream: go
> into the metadata subtrees of GROUP or TRANSACTION, and use that
> information in the loop2 nested elements, which are not in the metadata
> subtrees. That may not be possible.
>
> I found a solution with streaming accumulators for gathering the GROUP
> position:
>
> <xsl:accumulator name="group-position" as="xs:integer" initial-value="0"
> streamable="yes">
>  <xsl:accumulator-rule match="GROUP" select="$value + 1" />
> </xsl:accumulator>
>
> But I did not find a solution for gathering with a streaming accumulator,
> and then using the value of group-meta1, in the uri construction template.
> An accumulator as follows
> <xsl:accumulator name="group-meta" as="xs:integer" initial-value="0"
> streamable="yes">
>  <xsl:accumulator-rule match="group-meta1" select="." />
> </xsl:accumulator>
>
> Gives me an error that the accumulator needs to be motion less.
>
> Best,
>
> Felix
>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://-list/293509> (by email)
>
>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <-list/3033841> (by
> email <>)

Current Thread