Natavia Finnie
asked on
How do I loop through an XML data and get the node with the latest year and related data using xslt
This is part of the xml data:
I would like to get the latest of the EIVYEAR to get the EIVTOTAL for that year in my .xslt file
I would like to get the latest of the EIVYEAR to get the EIVTOTAL for that year in my .xslt file
-<EIVANNUALCOMP>
<EIVYEAR>2017</EIVYEAR>
<EIVBASE>56487.37</EIVBASE>
<EIVOVERTIME>0</EIVOVERTIME>
<EIVCOMMISSION>0</EIVCOMMISSION>
<EIVBONUS>13131.48</EIVBONUS>
<EIVOTHER>18403.7</EIVOTHER>
<EIVTOTAL>88022.55</EIVTOTAL>
</EIVANNUALCOMP>
-<EIVANNUALCOMP>
<EIVYEAR>2016</EIVYEAR>
<EIVBASE>24400.04</EIVBASE>
<EIVOVERTIME>1805.71</EIVOVERTIME>
<EIVCOMMISSION>510.46</EIVCOMMISSION>
<EIVBONUS>2400.16</EIVBONUS>
<EIVOTHER>20.1</EIVOTHER>
<EIVTOTAL>23171.95</EIVTOTAL>
</EIVANNUALCOMP>
because... this clumsy approach is only necessary in XSLT1... in XSLT2 you can use max()
XSLT 2.0
Or just this if there is only one occurrence of EIVANNUALCOMP per year
<xsl:template match="/">
<xsl:variable name="most-recent-year" select="max(//EIVANNUALCOMP/EIVYEAR)"/>
<xsl:value-of select="sum(//EIVANNUALCOMP[EIVYEAR = $most-recent-year]/EIVTOTAL)"/>
</xsl:template>
Or just this if there is only one occurrence of EIVANNUALCOMP per year
<xsl:template match="/">
<xsl:variable name="most-recent-year" select="max(//EIVANNUALCOMP/EIVYEAR)"/>
<xsl:value-of select="//EIVANNUALCOMP[EIVYEAR = $most-recent-year]/EIVTOTAL"/>
</xsl:template>
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
@Gertone
using this version:
how would I use it in here:
<xsl:call-template name="rowString">
<xsl:with-param name="label" select="'Salary: '" />
<xsl:with-param name="val" select="EIVTOTAL" />
</xsl:call-template>
using this version:
<xsl:template match="/">
<xsl:for-each select="//EIVANNUALCOMP">
<xsl:sort select="EIVYEAR" order="descending" data-type="number"/>
<xsl:if test="position() = 1">
<xsl:value-of select="EIVTOTAL"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
how would I use it in here:
<xsl:call-template name="rowString">
<xsl:with-param name="label" select="'Salary: '" />
<xsl:with-param name="val" select="EIVTOTAL" />
</xsl:call-template>
ASKER
@Gertone this one gives me an error saying
'max()' is an unknown XSLT function
'max()' is an unknown XSLT function
<xsl:template match="/">
<xsl:variable name="most-recent-year" select="max(//EIVANNUALCOMP/EIVYEAR)"/>
<xsl:value-of select="//EIVANNUALCOMP[EIVYEAR = $most-recent-year]/EIVTOTAL"/>
</xsl:template>
Please, read all my comments in detail
Max() is a xslt 2.0 function not supported in xslt 1.0
It seems you are using sn xslt 1.0 processor (my first question, left unanswered)
So you need to go for my xslt 1.0 solution with the sort and the for each
Max() is a xslt 2.0 function not supported in xslt 1.0
It seems you are using sn xslt 1.0 processor (my first question, left unanswered)
So you need to go for my xslt 1.0 solution with the sort and the for each
You can put the for each inside the with param “val” (and remove the select attribute then)
ASKER
@Gertone
Is it possible to get the data and store it in a variable to be used later in the file?
I have included some of the .xml to better understand
Is it possible to get the data and store it in a variable to be used later in the file?
I have included some of the .xml to better understand
-<OFX>
-<SIGNONMSGSRSV1>
-<SONRS>
-<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<DTSERVER>20201022165253</DTSERVER>
<LANGUAGE>ENG</LANGUAGE>
</SONRS>
</SIGNONMSGSRSV1>
-<EIVEMPLOYEEMSGSRSV1>
-<EIVIMMIGRATIONVERIFICATIONTRNRS>
<TRNUID>NA</TRNUID>
-<EIVIMMIGRATIONVERIFICATIONRS>
-<EIVANNUALCOMP>
<EIVYEAR>2017</EIVYEAR>
<EIVBASE>56487.37</EIVBASE>
<EIVOVERTIME>0</EIVOVERTIME>
<EIVCOMMISSION>0</EIVCOMMISSION>
<EIVBONUS>13131.48</EIVBONUS>
<EIVOTHER>18403.7</EIVOTHER>
<EIVTOTAL>88022.55</EIVTOTAL>
</EIVANNUALCOMP>
-<EIVANNUALCOMP>
<EIVYEAR>2016</EIVYEAR>
<EIVBASE>24400.04</EIVBASE>
<EIVOVERTIME>1805.71</EIVOVERTIME>
<EIVCOMMISSION>510.46</EIVCOMMISSION>
<EIVBONUS>2400.16</EIVBONUS>
<EIVOTHER>20.1</EIVOTHER>
<EIVTOTAL>23171.95</EIVTOTAL>
</EIVANNUALCOMP>
-<EIVANNUALCOMP>
<EIVYEAR>2015</EIVYEAR>
<EIVBASE>25415.41</EIVBASE>
<EIVOVERTIME>1705.38</EIVOVERTIME>
<EIVCOMMISSION>610.87</EIVCOMMISSION>
<EIVBONUS>2500.59</EIVBONUS>
<EIVOTHER>20.62</EIVOTHER>
<EIVTOTAL>23171.67</EIVTOTAL>
</EIVANNUALCOMP>
-<EIVANNUALCOMP>
<EIVYEAR>2014</EIVYEAR>
<EIVBASE>24400.04</EIVBASE>
<EIVOVERTIME>1805.71</EIVOVERTIME>
<EIVCOMMISSION>510.46</EIVCOMMISSION>
<EIVBONUS>2400.16</EIVBONUS>
<EIVOTHER>20.1</EIVOTHER>
<EIVTOTAL>23171.95</EIVTOTAL>
<EIVYEAR>2010</EIVYEAR>
<EIVBASE>29502</EIVBASE>
<EIVOVERTIME>4300</EIVOVERTIME>
<EIVCOMMISSION>2330</EIVCOMMISSION>
<EIVBONUS>830</EIVBONUS>
<EIVOTHER>163</EIVOTHER>
<EIVTOTAL>37123</EIVTOTAL>
</EIVANNUALCOMP>
<COMPLETENESS>IMMIGRATION</COMPLETENESS>
<SRVRTID>100245494397</SRVRTID>
</EIVIMMIGRATION_V100>
</EIVIMMIGRATIONVERIFICATIONRS>
</EIVIMMIGRATIONVERIFICATIONTRNRS>
</EIVEMPLOYEEMSGSRSV1>
</OFX>
first, if you send XML as an example, make sure you send the source XML, not the tree view from the browser)
(I am not going to bother pulling out all the collapsing dashes)
second, yes you can
(I am not going to bother pulling out all the collapsing dashes)
second, yes you can
- on line two of my first code sample there is an example to create a variable (you can construct inside the xsl:variable instead of having a select attribute like this
<xsl:variable name="most-recent-year"> <xsl:for-each select="//EIVANNUALCOMP"> ... </xsl:variable>
- further down I had the exact for each you could use
- Can you connect the dots yourself?
ASKER
@Gertone I apologize about the copy/paste. I'm dealing with coronavirus but still trying to work. I will try this!
Much appreciated!!!
Much appreciated!!!
take the first record
set the year in a variable
and sum the nodes from that year
how much XSLT do you already have, which processor, what version?
Do you have a full wellformed XML example (just want to rule out default namespaces uphill)