For-each through rows -1 in xslt - xslt-1.0

I have a question regarding xslt:
basically i have filtered rows:
<xsl:variable name="filteredRows" select="TestRows[(contains(#*[name()='FieldName'],#Title))]" />
And now i want to do for each on them but -1 so if there are 3 rows i want to execute for each only twice ... how to do that?
<xsl:for-each select ="$filteredRows - 1">
<xsl:text> label = </xsl:text>EMPTY
<br />
</xsl:for-each>
Thanks for help ..

Not tested (you didn't provide any sample), but <xsl:for-each select ="$filteredRow[position() < last()]"> could work.

Related

Trying to compare two strings in XSLT and outcome is not coming as expected

I'm trying to compare two strings in XSLT and wanted hard coded response as outcome
I have tried keeping an if condition in XSLT but it is providing me two results
<xsl:template name="variableTransformation">
<xsl:param name="text"/>
<xsl:param name="delimiters" select="' /-'"/>
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="nextDelimiter" select="substring(translate($text, translate($text, $delimiters, ''), ''), 1, 1)" />
<xsl:variable name="string" select="substring-before(concat($text, ' '), substring(concat($nextDelimiter, ' '), 1, 1))" />
<xsl:value-of select="translate(substring($string, 1, 1), $lower, $upper)"/>
<xsl:value-of select="translate(substring($string, 2), $upper, $lower)"/>
<xsl:if test="$nextDelimiter">
<xsl:value-of select="$nextDelimiter" />
<xsl:call-template name="variableTransformation">
<xsl:with-param name="text" select="substring-after($text, $nextDelimiter)"/>
<xsl:with-param name="delimiters" select="$delimiters"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="$text='SELF EMPLOYED'">
<xsl:value-of select="'Self-Employed'"></xsl:value-of>
</xsl:if>
<xsl:if test="$text='SKILL TRADE'">
<xsl:value-of select="'Skilled Trade'"></xsl:value-of>
</xsl:if>
</xsl:template>
input: 1. GOVERMENT 2. STUDENT 3. HOMEMAKER 4. PROFESSIONAL 5. SELF EMPLOYED 6. SERVICE/RETAIL 7. SKILL TRADE 8. UNEMPLOYED 9. OTHER
Expected:
Government
Student
Homemaker
Professional
Self-Employed
Service/Retail
Skilled Trade
Unemployed
Other
Actual:
Government
Student
Homemaker
Professional
Self EmployedSelf-Employed
Service/Retail
Skill TradeSkilled Trade
Unemployed
Other

xsl string-join() multiple variables - only use non-empty

I'd like to create several xsl:variable that may or may not be null then join them:
<xsl:variable name="creatorType" select="replace(lib:merge(subfields/subfield[matches(#code,'[e]')],' '),'author|[.$]','')" />
<xsl:variable name="creatorAttribution" select="replace(lib:merge(subfields/subfield[matches(#code,'[j]')],' '),'[,-.]$','')" />
<xsl:variable name="creatorNameFullForm" select="replace(lib:merge(subfields/subfield[matches(#code,'[q]')],' '),'[,-()]$','')" />
<xsl:variable name="creatorAffiliation" select="replace(lib:merge(subfields/subfield[matches(#code,'[u]')],' '),'[,-.]$','')" />
string-join((xsl:sequence), 'delimiter') seems like a good fit but also joins variables with empty values.
<xsl:variable name="creatorDescriptors" select ="string-join(($creatorDates, $creatorType, $creatorAttribution, $creatorAffiliation),', ')"/>
How would you have it only string-join non-null xsl:variables?
I'm currently getting something like this:
Mozart, Wolfgang Amadeus (1756–1791, Composer, , )
Try this expression instead (replacing the variable names with your own variable names), so that only the non-empty nodes are selected in the sequence
<xsl:value-of select="string-join(($a, $b, $c, $d)[. != ''],', ')"/>

How to sum the amounts in a xslt for same ids appearing in XML

I need to produce a text file in the output. I have to first check if a perosn has aby of the following node PreTaxAmt,MatchAmt,RothAmt, then produce a single line in output with required values and then I have to check if the perosn has LoanAmt node, if they have then I have to create another entry for that person. I was able to code till this point but now I am having a requiremnet where if the same person is repated more than once for example below laurel Alex , I need to produce just one entry for single participant id and the PreTaxAmt,MatchAmt,RothAmt amount should be summed up in the first entry in the output and in the in the loan entry row the LoanAmt should be summed up.
Here is my xml.
<Report_Data >
<Report_Entry>
<Participant_ID>03300</Participant_ID>
<Workers>
<FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator>
<Last_Name>Mary</Last_Name>
<First_Name>Mehul</First_Name>
</Workers>
<End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period>
<PreTaxAmt>100.8</PreTaxAmt>
<MatchAmt>100.8</MatchAmt>
<RothAmt>0</RothAmt>
<LoanAmt>0</LoanAmt>
</Report_Entry>
<Report_Entry>
<Participant_ID>10600</Participant_ID>
<Workers>
<FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator>
<Last_Name>Laurel</Last_Name>
<First_Name>Alex</First_Name>
</Workers>
<End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period>
<PreTaxAmt>61.48</PreTaxAmt>
<MatchAmt>61.47</MatchAmt>
<RothAmt>0</RothAmt>
<LoanAmt>0</LoanAmt>
</Report_Entry>
<Report_Entry>
<Participant_ID>10600</Participant_ID>
<Workers>
<FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator>
<Last_Name>Laurel</Last_Name>
<First_Name>Alex</First_Name>
<Middle_Name>S</Middle_Name>
</Workers>
<End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period>
<PreTaxAmt>0</PreTaxAmt>
<MatchAmt>0</MatchAmt>
<RothAmt>0</RothAmt>
<LoanAmt>0</LoanAmt>
</Report_Entry>
<Report_Entry>
<Participant_ID>13100</Participant_ID>
<Workers>
<FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator>
<Last_Name>Smita</Last_Name>
<First_Name>Paul</First_Name>
</Workers>
<End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period>
<PreTaxAmt>0</PreTaxAmt>
<MatchAmt>0</MatchAmt>
<RothAmt>0</RothAmt>
<LoanAmt>0</LoanAmt>
</Report_Entry>
Here is my xslt :
<xsl:template match="/">
<xsl:for-each select="Report_Data/Report_Entry">
<xsl:if test="(PreTaxAmt) or(MatchAmt) or (RothAmt) ">
<xsl:call-template name="DataRecords"/>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="Report_Data/Report_Entry">
<xsl:if test="LoanAmt">
<xsl:call-template name="LoanDataRecord"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="DataRecords">
<xsl:for-each-group select="." group-by="wd:Participant_ID">
<xsl:variable name="ParticpantLoan" select="current-grouping-key()"/>
!-- Transaction Code -->
<xsl:value-of select="'Contribution'"/>
<!-- Participant Number -->
<xsl:value-of select="Participant_ID,$filler),1,9"/>
<!-- FT/PT Indicator -->
<xsl:value-of select="substring(concat(Workers/FULL_PART_Time_Indicator,$filler),1,1)"/>
<!-- Contribution Amount1 -->
<xsl:value-of select="(sum(current-group()/PreTaxAmt))"/>
<!-- Contribution Amount2 -->
<xsl:value-of select="(sum(current-group()/MatchAmt))"/>
<!-- Contribution Amount3 -->
<xsl:value-of select="(sum(current-group()/RothAmt))"/>
<xsl:value-of select="$linefeed"/>
</xsl:for-each-group>
</xsl:template>
<xsl:template name="LoanDataRecord">
<xsl:for-each-group select="." group-by="Participant_ID">
<xsl:variable name="ParticpantLoan" select="current-grouping-key()"/>
<!-- Transaction Code -->
<xsl:value-of select="substring(concat('LoanData',$filler),1,3)"/>
<!-- Participant Number -->
<xsl:value-of select="substring(concat(Participant_ID,$filler),1,9)"/>
<!-- Loan Amt -->
<xsl:value-of select="(sum(current-group()/LoanAmt))"/>
<xsl:value-of select="$linefeed"/>
</xsl:for-each-group>
</xsl:template>
The output should have six lines.
Also, how can I calculate the total count of the records in my output file. Earlier I was using below code but now since there would be duplicate SSN how should I modify my existing code for counting ..
0 ] or Report_Data/Report_Entry/MatchAmt[number(.) > 0 ] or Report_Data/Report_Entry/RothAmt[number(.) > 0 ])+
count(Report_Data/Report_Entry/LoanAmt[number(.) > 0 ])

Get element value from XML datatype field

I want to retrieve element value from XML data field. Please check below code snippet for more detail:
SQL Script:
CREATE TABLE #Temp1 (ConfigXSLT XML);
INSERT INTO #Temp1 VALUES('<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" />
<xsl:variable name="transport">
<transport protocol="FILE" direction="get" filename="file1*.csv" />
</xsl:variable>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>')
-- I want only filename element value 'file1*.csv' in select statement
-- I have tried with below query but it not works
SELECT ConfigXSLT.value('declare namespace PD="http://www.w3.org/1999/XSL/Transform"; (//PD:variable/PD:transport/PD:filename)[1]','VARCHAR(MAX)')
FROM #Temp1
DROP TABLE #Temp1
You went overboard with using PD namespace (why PD btw?), the "transport" telement is without a namespace. Also, to select attribute you use # sign before the attributes name :)
Try this:
SELECT ConfigXSLT.value('declare namespace PD="http://www.w3.org/1999/XSL/Transform"; (//PD:variable/transport/#filename)[1]','VARCHAR(MAX)')
FROM #Temp1
Result:
file1*.csv
select #xml.value('(/stylesheet/variable/transport/#filename)[1]', 'nvarchar(max)')
Maybe something like that?

XSLT variable in predicate not working

my xml looks something like this:
<units>
<unit>
<unitnum></unitnum>
<Year></Year>
<Qty></Qty>
</unit>
</units>
I create a key to capture all the possible years. Like this:
<xsl:key name="yr" match="//Year/text()" use="." />
Then I for-each loop through the keys to get unique years. My ultimate goal is to sum the quantites like this:
<xsl:for-each select="//Year/text()[generate-id()=generate-id(key('yr',.)[1])]">
<li>
<xsl:variable name="varjobyear" select="."/>
<xsl:value-of select="$varjobyear"/> - sum -
<xsl:value-of select="sum(//unit[Year=$varjobyear]/Qty)"/>
</li>
</xsl:for-each>
For some reason my output looks like this:
2010 - sum - 0
2011 - sum - 0
2012 - sum - 0
But what I want is for those 0's to be the actual sum of the quantities for each year.
My best guess is that there is something wrong with the predicate [Year=$varjobyear], but I can't figure out what it is. I have also tried [Year=string($varjobyear)] and also [Year=number($varjobyear)].
What am I doing wrong? Thanks!
You want something like this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kYearByVal" match="Year" use="."/>
<xsl:template match="Year[generate-id()=generate-id(key('kYearByVal',.)[1])]">
<li>
<xsl:value-of select="concat(., ' - sum - ', sum(key('kYearByVal',.)/../Qty))"/>
</li>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
When this transformation is applied on the following XML document:
<units>
<unit>
<unitnum>12</unitnum>
<Year>1922</Year>
<Qty>3</Qty>
</unit>
<unit>
<unitnum>13</unitnum>
<Year>1922</Year>
<Qty>8</Qty>
</unit>
<unit>
<unitnum>14</unitnum>
<Year>1999</Year>
<Qty>5</Qty>
</unit>
<unit>
<unitnum>15</unitnum>
<Year>1999</Year>
<Qty>7</Qty>
</unit>
<unit>
<unitnum>16</unitnum>
<Year>2003</Year>
<Qty>3</Qty>
</unit>
</units>
the wanted, correct result is produced:
<li>1922 - sum - 11</li>
<li>1999 - sum - 12</li>
<li>2003 - sum - 3</li>