我有一个XML,其中包含工人和金额。在输出中,文件将包含一个工人的行 - 如果他有ER,则一行如果他有ER。如果他在XML文件中有Munter1,则他有EX,如果他有金额2,则有ER。在我当前的XSLT中,这很好。
主要问题是如何正确获取正确的行总数以及分组后的所有金额(金额1和金额2(的总和,并应在标题中添加。
这是示例XML:
<Report_Data>
<Report_Entry>
<Worker>
<Name>User1</Name>
<ID>1234</ID>
</Worker>
<amount1>-200</amount1>
<amount2>100</amount2>
</Report_Entry>
<Report_Entry>
<Worker>
<Name>User1</Name>
<ID>1234</ID>
</Worker>
<amount1>100</amount1>
<amount2>-50</amount2>
</Report_Entry>
<Report_Entry>
<Worker>
<Name>User2</Name>
<ID>5678</ID>
</Worker>
<amount1>-20</amount1>
<amount2>100</amount2>
</Report_Entry>
<Report_Entry>
<Worker>
<Name>User1</Name>
<ID>1234</ID>
</Worker>
<amount1>0</amount1>
<amount2>0</amount2>
</Report_Entry>
</Report_Data>
这是我的示例XSLT(我在柜台上工作,但不能正确。XML上的所有行值...(:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
xmlns:saxon="http://saxon.sf.net/" xmlns:ns0="urn:com.foo" extension-element-prefixes="saxon"
version="2.0">
<xsl:output method="text"/>
<xsl:variable name="SumOfAmount1" saxon:assignable="yes"/>
<xsl:variable name="SumOfAmount2" saxon:assignable="yes"/>
<xsl:variable name="countEX" as="xs:string*">
<xsl:for-each-group select="Report_Data/Report_Entry" group-by="Worker/ID">
<saxon:assign name="SumOfAmount1" select="sum(current-group()/Report_Data/Report_Entry/amount1)"/>
<xsl:if test="$SumOfAmount1 >= 0.00">
<xsl:sequence select="current-group()"></xsl:sequence>
</xsl:if>
</xsl:for-each-group>
</xsl:variable>
<xsl:variable name="countER" as="xs:string*">
<xsl:for-each-group select="/Report_Data/wd:Report_Entry" group-by="ID">
<saxon:assign name="SumOfAmount1" select="sum(current-group()/Report_Data/Report_Entry/amount2)"/>
<xsl:if test="$SumOfAmount1 >= 0.00">
<xsl:sequence select="current-group()"></xsl:sequence>
</xsl:if>
</xsl:for-each-group>
</xsl:variable>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Report_Data">
<Header>
<!--Total count of rows!-->
//add countER and countEX
<xsl:text>,</xsl:text>
<!--Sum of amount1 and amount2 !-->
//add total amounts
</Header>
<ReportData>
<xsl:for-each-group select="Report_Entry" group-by="Worker/ID">
<ReportEntry>
<xsl:copy-of select="current-group()[1]/*[starts-with(name(), 'ID')]"/>
</ReportEntry>
<saxon:assign name="SumOfAmount1" select="sum(current-group()/amount1)"/>
<saxon:assign name="SumOfAmount2" select="sum(current-group()/amount2)"/>
<xsl:if test="$SumOfAmount1 >= 0.00">
<xsl:call-template name="EX"></xsl:call-template>
</xsl:if>
<xsl:if test="$SumOfAmount2 >= 0.00">
<xsl:call-template name="ER"></xsl:call-template>
</xsl:if>
</xsl:for-each-group>
</ReportData>
</xsl:template>
<xsl:template name="EX">
<Name>
<xsl:value-of select="Worker/Name"/>
</Name>
<xsl:text>,</xsl:text>
<ID>
<xsl:value-of select="Worker/ID"/>
</ID>
<xsl:text>,</xsl:text>
<amount1>
<xsl:value-of select="$SumOfAmount1"/>
</amount1>
<xsl:text>,</xsl:text>
<xsl:value-of select="'EX'"></xsl:value-of>
<xsl:value-of select="'
'"></xsl:value-of>
</xsl:template>
<xsl:template name="ER">
<Name>
<xsl:value-of select="Worker/Name"/>
</Name>
<xsl:text>,</xsl:text>
<ID>
<xsl:value-of select="Worker/ID"/>
</ID>
<xsl:text>,</xsl:text>
<amount1>
<xsl:value-of select="$SumOfAmount2"/>
</amount1>
<xsl:text>,</xsl:text>
<xsl:value-of select="'ER'"></xsl:value-of>
<xsl:value-of select="'
'"></xsl:value-of>
</xsl:template>
</xsl:stylesheet>
预期输出:
2,150
User1,1234,50,ER
User2,5678,100,ER
其中:2是行的数量,150是所有金额的总和(MANES1和MANES2(。
P.S。负数不包括在文件中。如果量表1或金额2为负,则将其包含在加法中,但是如果总额为负,则将被排除并且未显示在文件中。
感谢您的帮助。
我将通过ID进行一次分组,然后根据是否有amount1/amount2
元素存储行数据。为了计算总和,我只需再次选择元素:
<xsl:template match="/">
<xsl:variable name="rows" as="element(row)*">
<xsl:for-each-group select="Report_Data/Report_Entry" group-by="Worker/ID">
<xsl:if test="current-group()/amount1">
<row>
<xsl:value-of select="Worker/Name, current-grouping-key(), sum(current-group()/amount1), 'EX'" separator=","/>
</row>
</xsl:if>
<xsl:if test="current-group()/amount2">
<row>
<xsl:value-of select="Worker/Name, current-grouping-key(), sum(current-group()/amount2), 'ER'" separator=","/>
</row>
</xsl:if>
</xsl:for-each-group>
</xsl:variable>
<xsl:value-of select="count($rows), sum(Report_Data/Report_Entry/*[starts-with(local-name(), 'amount')]), $rows" separator=" "/>
</xsl:template>
http://xsltfiddle.liberty-development.net/bdxtpa
看来我没有完全正确的格式,请参阅http://xsltfiddle.liberty-development.net/bdxtpa/1使用
的校正 <xsl:value-of select="concat(count($rows), ',', sum(Report_Data/Report_Entry/*[starts-with(local-name(), 'amount')])), $rows" separator=" "/>
对于消除群体的精致要求,总额为负数为负,我认为
<xsl:template match="/">
<xsl:variable name="rows" as="element(row)*">
<xsl:for-each-group select="Report_Data/Report_Entry" group-by="Worker/ID">
<xsl:variable name="sum1" select="sum(current-group()/amount1)"/>
<xsl:if test="current-group()/amount1 and $sum1 > 0">
<row sum="{$sum1}">
<xsl:value-of select="Worker/Name, current-grouping-key(), $sum1, 'EX'" separator=","/>
</row>
</xsl:if>
<xsl:variable name="sum2" select="sum(current-group()/amount2)"/>
<xsl:if test="current-group()/amount2 and $sum2 > 0">
<row sum="{$sum2}">
<xsl:value-of select="Worker/Name, current-grouping-key(), $sum2, 'ER'" separator=","/>
</row>
</xsl:if>
</xsl:for-each-group>
</xsl:variable>
<xsl:value-of select="concat(count($rows), ',', sum($rows/@sum)), $rows" separator=" "/>
</xsl:template>
这样做:http://xsltfiddle.liberty-development.net/bdxtpa/2