我对文件格式有如下要求,我需要获取行数和字段的总和。在该示例中,具有三列的列具有金额值,而在第四行中,我需要总行数和要填充的金额之和。
Alex, Scot 10091978 90.00
Brad, Ander 23061976 40.00
Rodney, Philips 04091983 35.00
03 165.00
XML输入
<wd:Report_Data
xmlns:wd="urn:com.workday.report/INT001_Test_Reward_Report">
<wd:Report_Entry>
<wd:Worker_group>
<wd:Employee_ID>12344</wd:Employee_ID>
<wd:dateOfBirth>1975-05-06</wd:dateOfBirth>
<wd:lastName>Alex</wd:lastName>
<wd:firstName>Scot</wd:firstName>
<wd:Pay_Frequency>M1</wd:Pay_Frequency>
</wd:Worker_group>
<wd:Payroll_Result_group>
<wd:Payment_Date>2019-04-02</wd:Payment_Date>
</wd:Payroll_Result_group>
<wd:Payroll_Result_Line_group>
<wd:Result_Line_Amount>40</wd:Result_Line_Amount>
</wd:Payroll_Result_Line_group>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_group>
<wd:Employee_ID>12355</wd:Employee_ID>
<wd:dateOfBirth>1958-05-06</wd:dateOfBirth>
<wd:lastName>Hyrus</wd:lastName>
<wd:firstName>Marike</wd:firstName>
<wd:Pay_Frequency>M1</wd:Pay_Frequency>
</wd:Worker_group>
<wd:Payroll_Result_group>
<wd:Payment_Date>2019-04-04</wd:Payment_Date>
</wd:Payroll_Result_group>
<wd:Payroll_Result_Line_group>
<wd:Result_Line_Amount>10</wd:Result_Line_Amount>
</wd:Payroll_Result_Line_group>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_group>
<wd:Employee_ID>12366</wd:Employee_ID>
<wd:dateOfBirth>1986-09-10</wd:dateOfBirth>
<wd:lastName>Elite</wd:lastName>
<wd:firstName>Samsung</wd:firstName>
<wd:Pay_Frequency>M1</wd:Pay_Frequency>
</wd:Worker_group>
<wd:Payroll_Result_group>
<wd:Payment_Date>2019-04-02</wd:Payment_Date>
</wd:Payroll_Result_group>
<wd:Payroll_Result_Line_group>
<wd:Result_Line_Amount>30</wd:Result_Line_Amount>
</wd:Payroll_Result_Line_group>
</wd:Report_Entry>
</wd:Report_Data>
XSLT I have tried so far
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wd="urn:com.workday.report/INT001_Test_Reward_Report"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:this="urn:this-stylesheet"
version="2.0" exclude-result-prefixes="xs this">
<!--**************************************************************************************-->
<!-- Date XSLT Attachment Design -->
<!-- 06-17-2019 Transformation to transform file format from xml to .txt(fixed ) -->
<!--**************************************************************************************-->
<!-- 06-17-2019 Initial Version -->
<!--**************************************************************************************-->
<!--The final output file will be text formatted with an encoding of *NA*-->
<xsl:output encoding="UTF-8" method="text" use-character-maps="custom-char-filter" />
<!--declare global variables here such as delimiter and linefeed-->
<xsl:variable name="vDelimiter" select="''"/>
<xsl:variable name="linefeed" select="' '" />
<xsl:variable name="linefeed2" select="'
'"/>
<xsl:variable name="vWrapQuotes" select="false()"/>
<xsl:variable name="vDateFormat" select="'[Y0001][M01][D01]'"/>
<xsl:variable name="vDateTimeFormat" select="'[D01]-[MN,*-3]-[Y0001]T[H01]:[m01]:[s01]'"/>
<xsl:variable name="pDateValue" select="current-date()"/>
<xsl:variable name="SumAmount" select="0"/>
<xsl:variable name="i" select="0"/>
<!--Root Template-->
<xsl:template match="wd:Report_Data">
<!--declare root variables here such as current datetime or other repeating values-->
<xsl:value-of select="this:setOutput(this:formatDate($pDateValue))" />
<xsl:value-of select="$linefeed"/>
<!--Process detail records-->
<xsl:apply-templates select="wd:Report_Entry" />
<xsl:text>T</xsl:text>
<xsl:value-of select="$i"/>
<xsl:value-of select="$SumAmount"/>
</xsl:template>
<!--Detail Record Template-->
<xsl:template match="wd:Report_Entry">
<!--
Detail Record
-->
<!--Record Type - -->
<xsl:text>D</xsl:text>
<xsl:value-of select="this:setOutput(this:fixedWidth(wd:Worker_group/wd:Employee_ID, ' ', 8, 'left'))" />
<xsl:value-of select="this:setOutput(this:fixedWidth((this:formatDate(wd:Worker_group/wd:dateOfBirth)), ' ', 8, 'left'))" />
<xsl:value-of select="this:setOutput(this:fixedWidth(wd:Worker_group/wd:lastName, ' ', 40,'left'))" />
<xsl:value-of select="this:setOutput(this:fixedWidth(wd:Worker_group/wd:firstName, ' ', 40, 'left'))" />
<xsl:value-of select="this:setOutput(this:fixedWidth(wd:Payroll_Result_Line_group/wd:Result_Line_Amount, ' ', 9, 'left'))" />
<xsl:value-of select="this:setOutput(this:fixedWidth(wd:Worker_group/wd:Pay_Frequency, ' ', 2, 'left'))" />
<xsl:value-of select="this:setOutput(this:fixedWidth((this:formatDate(wd:Payroll_Result_group/wd:Payment_Date)), ' ', 8, 'left'))" />
<xsl:variable name="Amount" select="this:setOutput(wd:Payroll_Result_Line_group/wd:Result_Line_Amount)"/>
<xsl:value-of select="$Amount"/>
<xsl:variable name="i" select="position()"/>
<xsl:value-of select="$i"/>
<xsl:variable name="SumAmount" select="$SumAmount + $Amount"/>
<xsl:value-of select="$linefeed" />
</xsl:template>
<!--******************************************************************************************** -->
<!--This function returns the input value followed by a delmiter -->
<!--******************************************************************************************** -->
<xsl:function name="this:setOutput">
<xsl:param name="value" />
<xsl:value-of select="this:setOutput($value,false())"/>
</xsl:function>
<!--******************************************************************************************** -->
<!--This function returns the input value followed by a delmiter -->
<!--******************************************************************************************** -->
<xsl:function name="this:setOutput">
<xsl:param name="value" />
<xsl:param name="finalValue" as="xs:boolean"/>
<xsl:variable name="vWrappedValue">
<xsl:value-of select="if($vWrapQuotes = false()) then $value else this:wrapQuotes($value)"/>
</xsl:variable>
<xsl:value-of select="if ($finalValue = false()) then concat(string($vWrappedValue),$vDelimiter) else $vWrappedValue"/>
</xsl:function>
<!--******************************************************************************************** -->
<!--This function is designed to wrap a string in quotes if required -->
<!--******************************************************************************************** -->
<xsl:function name="this:wrapQuotes">
<xsl:param name="field"/>
<xsl:value-of select="'"'"/>
<xsl:value-of select="replace($field,'"','""')"/>
<xsl:value-of select="'"'"/>
</xsl:function>
<!--******************************************************************************************** -->
<!--This function is designed to pad a string to the left or right to a fixed number of characters-->
<!-- str: a string input -->
<!-- chr: a character used for padding -->
<!-- len: a number of defining the total length of the output -->
<!-- dir: the direction of the alignment default is left; right if specified) -->
<!-- Note: if something is aligned left it will be padded on the right and vice versa -->
<!--******************************************************************************************** -->
<xsl:function name="this:padString">
<xsl:param name="str" />
<xsl:param name="chr" />
<xsl:param name="len" />
<xsl:param name="dir" />
<xsl:variable name="padLength">
<xsl:value-of select="$len - string-length($str)" />
</xsl:variable>
<xsl:variable name="pad">
<xsl:for-each select="1 to $padLength">
<xsl:value-of select="$chr" />
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="if ($dir = 'right') then concat($str,$pad) else concat($pad,$str)" />
</xsl:function>
<!--******************************************************************************************** -->
<!--This function is designed to align a string to the left or right to a fixed number of characters-->
<!-- str: a string input -->
<!-- chr: a character used for padding -->
<!-- len: a number of defining the total length of the output -->
<!-- dir: the direction of the alignment default is left; right if specified) -->
<!-- Note: if something is aligned left it will be padded on the right and vice versa -->
<!--******************************************************************************************** -->
<xsl:function name="this:fixedWidth">
<xsl:param name="str" />
<xsl:param name="chr" />
<xsl:param name="len" />
<xsl:param name="dir" />
<xsl:variable name="padLength">
<xsl:value-of select="$len - string-length($str)" />
</xsl:variable>
<xsl:variable name="pad">
<xsl:for-each select="1 to $padLength">
<xsl:value-of select="$chr" />
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="if ($dir = 'right') then substring(concat($pad,$str),1,$len) else substring(concat($str,$pad),1,$len)" />
</xsl:function>
<!--******************************************************************************************** -->
<!--This function can be modified as needed for the appropriate date format -->
<!--******************************************************************************************** -->
<xsl:function name="this:formatDate">
<xsl:param name="pDateValue" />
<xsl:value-of select="if (xs:string($pDateValue) = '') then '' else format-date(xs:date($pDateValue), $vDateFormat)" />
</xsl:function>
<xsl:function name="this:formatDateTime">
<xsl:param name="pDateTimeValue" />
<xsl:value-of select="if ($pDateTimeValue = '') then '' else format-dateTime(xs:dateTime($pDateTimeValue),$vDateTimeFormat )" />
</xsl:function>
<!--************************************************************************************************* -->
<!--Character Maps can be used to replace special and/or foreign characters where appropriate -->
<!--The big avantage is that these don't have to be called explicitly, the processor will handle this -->
<!--while writing the output. -->
<!--************************************************************************************************* -->
<xsl:character-map name="custom-char-filter">
<xsl:output-character character="*" string="" />
<xsl:output-character character=":" string="" />
<xsl:output-character character="^" string="" />
<xsl:output-character character="~" string="" />
</xsl:character-map>
</xsl:stylesheet>
我还尝试了一些xslt函数(总计数,总行计数), 但似乎没有任何效果。
谢谢, Jithendra。
答案 0 :(得分:0)
请考虑以下简化示例:
XML
<wd:Report_Data xmlns:wd="urn:com.workday.report/INT001_Test_Reward_Report">
<wd:Report_Entry>
<wd:Worker_group>
<wd:lastName>Alex</wd:lastName>
<wd:firstName>Scot</wd:firstName>
</wd:Worker_group>
<wd:Payroll_Result_Line_group>
<wd:Result_Line_Amount>90</wd:Result_Line_Amount>
</wd:Payroll_Result_Line_group>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_group>
<wd:lastName>Brad</wd:lastName>
<wd:firstName>Ander</wd:firstName>
</wd:Worker_group>
<wd:Payroll_Result_Line_group>
<wd:Result_Line_Amount>40</wd:Result_Line_Amount>
</wd:Payroll_Result_Line_group>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_group>
<wd:lastName>Rodney</wd:lastName>
<wd:firstName>Philips</wd:firstName>
</wd:Worker_group>
<wd:Payroll_Result_Line_group>
<wd:Result_Line_Amount>35</wd:Result_Line_Amount>
</wd:Payroll_Result_Line_group>
</wd:Report_Entry>
</wd:Report_Data>
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="urn:com.workday.report/INT001_Test_Reward_Report">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/wd:Report_Data">
<!-- records -->
<xsl:for-each select="wd:Report_Entry">
<xsl:value-of select="wd:Worker_group/wd:lastName"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="wd:Worker_group/wd:firstName"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="wd:Payroll_Result_Line_group/wd:Result_Line_Amount"/>
<xsl:text> </xsl:text>
</xsl:for-each>
<!-- summary -->
<xsl:value-of select="count(wd:Report_Entry)"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="sum(wd:Report_Entry/wd:Payroll_Result_Line_group/wd:Result_Line_Amount)"/>
</xsl:template>
</xsl:stylesheet>
结果
Alex, Scot 90
Brad, Ander 40
Rodney, Philips 35
3 165