Re: [xsl] How to incrementally add to a result document?

Subject: Re: [xsl] How to incrementally add to a result document?
From: "Martin Honnen martin.honnen@xxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 29 Jun 2024 09:29:22 -0000
On 28/06/2024 23:39, Roger L Costello costello@xxxxxxxxx wrote:
> Is there anyway that I can achieve what I desire -- output to one
> document the result of mapping the old form to the new form and output
> to another document metadata that describes the mapping steps that were
> taken? Or is this outside the realm of XSLT's capabilities?


One approach using the various suggestions made could be XSLT 3 with an
accumulator storing your log data and then writing it out to a result
document:


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 B  version="3.0"
 B  xmlns:xs="http://www.w3.org/2001/XMLSchema";
 B  exclude-result-prefixes="#all"
 B  expand-text="yes">

 B  <xsl:accumulator name="log-data" as="element(mapping)*"
initial-value="()">

 B B B  <xsl:accumulator-rule match="Airport_Name">
 B B B B B  <xsl:variable name="mapping" as="element(mapping)">
 B B B B B B B  <mapping>
 B B B B B B B B B B B  <legacy-elmt-name>
 B B B B B B B B B B B B B B B  <xsl:value-of select="name()"/>
 B B B B B B B B B B B  </legacy-elmt-name>
 B B B B B B B B B B B  <legacy-elmt-value>
 B B B B B B B B B B B B B B B  <xsl:value-of select="."/>
 B B B B B B B B B B B  </legacy-elmt-value>
 B B B B B B B B B B B  <new-elmt-name>
 B B B B B B B B B B B B B B B  <xsl:text>name</xsl:text>
 B B B B B B B B B B B  </new-elmt-name>
 B B B B B B B B B B B  <new-elmt-value>
 B B B B B B B B B B B B B B B  <xsl:value-of select="normalize-space(.)"/>
 B B B B B B B B B B B  </new-elmt-value>
 B B B B B B B  </mapping>
 B B B B B  </xsl:variable>
 B B B B B  <xsl:sequence select="$value, $mapping"/>
 B B B  </xsl:accumulator-rule>

 B B B  <xsl:accumulator-rule match="Airport_Elevation">
 B B B B B  <xsl:variable name="mapping" as="element(mapping)">
 B B B B B B B  <mapping>
 B B B B B B B B B B B  <legacy-elmt-name>
 B B B B B B B B B B B B B B B  <xsl:value-of select="name()"/>
 B B B B B B B B B B B  </legacy-elmt-name>
 B B B B B B B B B B B  <legacy-elmt-value>
 B B B B B B B B B B B B B B B  <xsl:value-of select="."/>
 B B B B B B B B B B B  </legacy-elmt-value>
 B B B B B B B B B B B  <new-elmt-name>
 B B B B B B B B B B B B B B B  <xsl:text>elevation</xsl:text>
 B B B B B B B B B B B  </new-elmt-name>
 B B B B B B B B B B B  <new-elmt-value>
 B B B B B B B B B B B B B B B  <xsl:if test=". castable as xs:integer">
 B B B B B B B B B B B B B B B B B B B  <xsl:value-of select="xs:integer(.)"/>
 B B B B B B B B B B B B B B B  </xsl:if>
 B B B B B B B B B B B  </new-elmt-value>
 B B B B B B B  </mapping>
 B B B B B  </xsl:variable>
 B B B B B  <xsl:sequence select="$value, $mapping"/>
 B B B  </xsl:accumulator-rule>
 B  </xsl:accumulator>

 B  <xsl:template match="Airport">
 B B B  <airport>
 B B B B B  <xsl:apply-templates select="Airport_Name"/>
 B B B B B  <xsl:apply-templates select="Airport_Elevation"/>
 B B B B B  <xsl:result-document href="metadata.xml">
 B B B B B B B  <mappings>
 B B B B B B B B B  <xsl:sequence select="accumulator-after('log-data')"/>
 B B B B B B B  </mappings>
 B B B B B  </xsl:result-document>
 B B B  </airport>
 B  </xsl:template>

 B  <xsl:template match="Airport_Name">
 B B B  <name>
 B B B B B  <xsl:value-of select="normalize-space(.)"/>
 B B B  </name>
 B  </xsl:template>

 B  <xsl:mode on-no-match="shallow-copy" use-accumulators="log-data"/>

 B  <xsl:output indent="yes"/>

</xsl:stylesheet>


Example SaxonJS 2 fiddle
<https://martin-honnen.github.io/xslt3fiddle/?xslt=%3C%3Fxml+version%3D%221.0
%22+encoding%3D%22utf-8%22%3F%3E%0D%0A%3Cxsl%3Astylesheet+xmlns%3Axsl%3D%22ht
tp%3A%2F%2Fwww.w3.org%2F1999%2FXSL%2FTransform%22%0D%0A++version%3D%223.0%22%
0D%0A++xmlns%3Axs%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema%22%0D%0A++e
xclude-result-prefixes%3D%22%23all%22%0D%0A++expand-text%3D%22yes%22%3E%0D%0A
++%0D%0A++%3Cxsl%3Aaccumulator+name%3D%22log-data%22+as%3D%22element%28mappin
g%29*%22+initial-value%3D%22%28%29%22%3E%0D%0A++++%0D%0A++++%3Cxsl%3Aaccumula
tor-rule+match%3D%22Airport_Name%22%3E%0D%0A++++++%3Cxsl%3Avariable+name%3D%2
2mapping%22+as%3D%22element%28mapping%29%22%3E%0D%0A++++++++%3Cmapping%3E%0D%
0A++++++++++++%3Clegacy-elmt-name%3E%0D%0A++++++++++++++++%3Cxsl%3Avalue-of+s
elect%3D%22name%28%29%22%2F%3E%0D%0A++++++++++++%3C%2Flegacy-elmt-name%3E%0D%
0A++++++++++++%3Clegacy-elmt-value%3E%0D%0A++++++++++++++++%3Cxsl%3Avalue-of+
select%3D%22.%22%2F%3E%0D%0A++++++++++++%3C%2Flegacy-elmt-value%3E%0D%0A+++++
+++++++%3Cnew-elmt-name%3E%0D%0A++++++++++++++++%3Cxsl%3Atext%3Ename%3C%2Fxsl
%3Atext%3E%0D%0A++++++++++++%3C%2Fnew-elmt-name%3E%0D%0A++++++++++++%3Cnew-el
mt-value%3E%0D%0A++++++++++++++++%3Cxsl%3Avalue-of+select%3D%22normalize-spac
e%28.%29%22%2F%3E%0D%0A++++++++++++%3C%2Fnew-elmt-value%3E%0D%0A++++++++%3C%2
Fmapping%3E%0D%0A++++++%3C%2Fxsl%3Avariable%3E%0D%0A++++++%3Cxsl%3Asequence+s
elect%3D%22%24value%2C+%24mapping%22%2F%3E%0D%0A++++%3C%2Fxsl%3Aaccumulator-r
ule%3E%0D%0A++++%0D%0A++++%3Cxsl%3Aaccumulator-rule+match%3D%22Airport_Elevat
ion%22%3E%0D%0A++++++%3Cxsl%3Avariable+name%3D%22mapping%22+as%3D%22element%2
8mapping%29%22%3E%0D%0A++++++++%3Cmapping%3E%0D%0A++++++++++++%3Clegacy-elmt-
name%3E%0D%0A++++++++++++++++%3Cxsl%3Avalue-of+select%3D%22name%28%29%22%2F%3
E%0D%0A++++++++++++%3C%2Flegacy-elmt-name%3E%0D%0A++++++++++++%3Clegacy-elmt-
value%3E%0D%0A++++++++++++++++%3Cxsl%3Avalue-of+select%3D%22.%22%2F%3E%0D%0A+
+++++++++++%3C%2Flegacy-elmt-value%3E%0D%0A++++++++++++%3Cnew-elmt-name%3E%0D
%0A++++++++++++++++%3Cxsl%3Atext%3Eelevation%3C%2Fxsl%3Atext%3E%0D%0A++++++++
++++%3C%2Fnew-elmt-name%3E%0D%0A++++++++++++%3Cnew-elmt-value%3E%0D%0A+++++++
+++++++++%3Cxsl%3Aif+test%3D%22.+castable+as+xs%3Ainteger%22%3E%0D%0A++++++++
++++++++++++%3Cxsl%3Avalue-of+select%3D%22xs%3Ainteger%28.%29%22%2F%3E%0D%0A+
+++++++++++++++%3C%2Fxsl%3Aif%3E%0D%0A++++++++++++%3C%2Fnew-elmt-value%3E%0D%
0A++++++++%3C%2Fmapping%3E%0D%0A++++++%3C%2Fxsl%3Avariable%3E%0D%0A++++++%3Cx
sl%3Asequence+select%3D%22%24value%2C+%24mapping%22%2F%3E%0D%0A++++%3C%2Fxsl%
3Aaccumulator-rule%3E%0D%0A++%3C%2Fxsl%3Aaccumulator%3E%0D%0A++%0D%0A++%3Cxsl
%3Atemplate+match%3D%22Airport%22%3E%0D%0A++++%3Cairport%3E%0D%0A++++++%3Cxsl
%3Aapply-templates+select%3D%22Airport_Name%22%2F%3E%0D%0A++++++%3Cxsl%3Aappl
y-templates+select%3D%22Airport_Elevation%22%2F%3E%0D%0A++++++%3Cxsl%3Aresult
-document+href%3D%22metadata.xml%22%3E%0D%0A++++++++%3Cmappings%3E%0D%0A+++++
+++++%3Cxsl%3Asequence+select%3D%22accumulator-after%28%27log-data%27%29%22%2
F%3E%0D%0A++++++++%3C%2Fmappings%3E%0D%0A++++++%3C%2Fxsl%3Aresult-document%3E
%0D%0A++++%3C%2Fairport%3E%0D%0A++%3C%2Fxsl%3Atemplate%3E%0D%0A++%0D%0A++%3Cx
sl%3Atemplate+match%3D%22Airport_Name%22%3E%0D%0A++++%3Cname%3E%0D%0A++++++%3
Cxsl%3Avalue-of+select%3D%22normalize-space%28.%29%22%2F%3E%0D%0A++++%3C%2Fna
me%3E%0D%0A++%3C%2Fxsl%3Atemplate%3E%0D%0A%0D%0A++%3Cxsl%3Amode+on-no-match%3
D%22shallow-copy%22+use-accumulators%3D%22log-data%22%2F%3E%0D%0A++%0D%0A++%3
Cxsl%3Aoutput+indent%3D%22yes%22%2F%3E%0D%0A%0D%0A++%3Cxsl%3Atemplate+match%3
D%22%2F%22+name%3D%22xsl%3Ainitial-template%22%3E%0D%0A++++%3Cxsl%3Anext-matc
h%2F%3E%0D%0A++++%3Cxsl%3Acomment%3ERun+with+%7Bsystem-property%28%27xsl%3Apr
oduct-name%27%29%7D+%7Bsystem-property%28%27xsl%3Aproduct-version%27%29%7D+%7
Bsystem-property%28%27Q%7Bhttp%3A%2F%2Fsaxon.sf.net%2F%7Dplatform%27%29%7D%3C
%2Fxsl%3Acomment%3E%0D%0A++%3C%2Fxsl%3Atemplate%3E%0D%0A++%0D%0A%3C%2Fxsl%3As
tylesheet%3E%0D%0A&input=%3CAirport%3E%0D%0A++%3CAirport_Name%3EBoston+Logan+
Airport%3C%2FAirport_Name%3E%0D%0A++%3CAirport_Elevation%3E19%3C%2FAirport_El
evation%3E%0D%0A%3C%2FAirport%3E%0D%0A&input-type=XML>.

Current Thread