需要根据两个元素对节点进行分组,并对第三个元素进行求和。关键是什么?变量?

3

非常感谢您的帮助。
我有一个大型的xml文件,需要合并/汇总行。我花了很多时间去研究我的XSLT For Dummies书中的内容,并尝试了许多论坛上的方案,但是我离目标还很远。如果您能提供任何指导,我将非常感激。

    <Report>    
        <Report_Entry>
            <POSTING-DATE>02292016</POSTING-DATE>
            <pmtdt>2016-02-29-08:00</pmtdt>
            <emp>10025</emp>
            <cc>020107450</cc>
            <union>N10025</union>
            <fac>000002010</fac>
            <job>8062</job>
            <pay>RGR</pay>
            <hours>2</hours>
        </Report_Entry>
        <Report_Entry>
            <POSTING-DATE>02292016</POSTING-DATE>
            <pmtdt>2016-02-29-08:00</pmtdt>
            <emp>10025</emp>
            <cc>020107450</cc>
            <union>N10025</union>
            <fac>000002010</fac>
            <job>8062</job>
            <pay>RGR</pay>
            <hours>110.27</hours>
        </Report_Entry>
        <Report_Entry>
            <POSTING-DATE>02292016</POSTING-DATE>
            <pmtdt>2016-02-29-08:00</pmtdt>
            <emp>10025</emp>
            <cc>020107450</cc>
            <union>N10025</union>
            <fac>000002010</fac>
            <job>8062</job>
            <pay>RGR</pay>
            <hours>61.07</hours>
        </Report_Entry>
       <Report_Entry>
            <POSTING-DATE>02292016</POSTING-DATE>
            <pmtdt>2016-02-29-08:00</pmtdt>
            <emp>10025</emp>
            <cc>020107450</cc>
            <union>N10025</union>
            <fac>000002010</fac>
            <job>8062</job>
            <pay>SAL</pay>
            <hours>2.01</hours>
        </Report_Entry>
        <Report_Entry>
            <POSTING-DATE>02292016</POSTING-DATE>
            <pmtdt>2016-02-29-08:00</pmtdt>
            <emp>10058</emp>
            <cc>020107375</cc>
            <union>N10058</union>
            <fac>000002010</fac>
            <job>8085</job>
            <pay>SAL</pay>
            <hours>130</hours>
        </Report_Entry>
        <Report_Entry>
            <POSTING-DATE>02292016</POSTING-DATE>
            <pmtdt>2016-02-29-08:00</pmtdt>
            <emp>10102</emp>
            <cc>020267515</cc>
            <union>N10102</union>
            <fac>000002026</fac>
            <job>8066</job>
            <pay>BLV</pay>
            <hours>31</hours>
        </Report_Entry>
        <Report_Entry>
            <POSTING-DATE>02292016</POSTING-DATE>
            <pmtdt>2016-02-29-08:00</pmtdt>
            <emp>10102</emp>
            <cc>020267515</cc>
            <union>N10102</union>
            <fac>000002026</fac>
            <job>8066</job>
            <pay>SAL</pay>
            <hours>125</hours>
        </Report_Entry>
        <Report_Entry>
            <POSTING-DATE>02292016</POSTING-DATE>
            <pmtdt>2016-02-29-08:00</pmtdt>
            <emp>10102</emp>
            <cc>020267515</cc>
            <union>N10102</union>
            <fac>000002026</fac>
            <job>8066</job>
            <pay>SAL</pay>
            <hours>125</hours>
        </Report_Entry>
        <Report_Entry>
            <POSTING-DATE>02292016</POSTING-DATE>
            <pmtdt>2016-02-29-08:00</pmtdt>
            <emp>10102</emp>
            <cc>020267515</cc>
            <union>N10102</union>
            <fac>000002026</fac>
            <job>8066</job>
            <pay>VOL</pay>
            <hours>15</hours>
        </Report_Entry>
    </Report_Data>  

我的预期输出是每个员工/薪资组合的一行数据,并将相关的小时数总计:
      N10025        000002010   8062    RGR 173.34
      N10025        000002010   8062    SAL 2.01
      N10058        000002010   8085    SAL 130
      N10102        000002026   8066    BLV 31
      N10102        000002026   8066    SAL 250
      N10102        000002026   8066    VOL 15

我本来考虑不发布我的XSL文件,但那样做很不礼貌。请不要笑得太厉害...

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:rd="urn:com.abcd.report/Report" 
     version="3.0">

    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="emp" match="/Report_Data/Report_Entry/emp" use="text()"/>
    <xsl:key name="pay" match="/Report_Data/Report_Entry/pay" use="text()"/> 
    <xsl:variable name="newline" select="'&#xD;'"/>
    <xsl:variable name="sep" select="'&#124;'"/>    

    <xsl:template match="Report_Data/Report_Entry">
        <file>
             <line>
                 <xsl:for-each select = "emp[generate-id(.)=generate-id(key('emp',text())]">
                 <xsl:for-each select="key('emp',"'wd:pay')">
                      <xsl:if test="./text()=*/text()">
                           <!-- This is embarrassing -->
                     </xsl:if>
                 </xsl:for-each>                
             </xsl:for-each>    
           </line>
       </file>
    </xsl:template>
    </xsl:stylesheet>

你的样式表标记为XSLT 3.0 - 你的处理器是否支持(至少)XSLT 2.0? - michael.hor257k
“N10025 000002010 8062 RGR 173.34” 对我来说看起来像纯文本,您能解释一下这是您期望的输出格式还是它与您XSLT中的“line”元素有什么关系吗? - Martin Honnen
2个回答

1

XSLT 1.0使用Muenchian Method

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes"/>

  <xsl:key name="k" match="Report_Entry" use="concat(emp, '|', pay)"/>

  <xsl:template match="/">
    <xsl:apply-templates 
      select="//Report_Entry[generate-id() = generate-id(key('k', concat(emp, '|', pay)))]"/>
  </xsl:template>

  <xsl:template match="Report_Entry">
    <xsl:value-of 
      select="concat(union, '        ', fac, ' ', job, ' ', pay, ' ',
        sum(key('k', concat(emp, '|', pay))/hours))"/>
    <xsl:text>
</xsl:text>
  </xsl:template>

</xsl:stylesheet>

输入:

<Report>
  <Report_Entry>
    <POSTING-DATE>02292016</POSTING-DATE>
    <pmtdt>2016-02-29-08:00</pmtdt>
    <emp>10025</emp>
    <cc>020107450</cc>
    <union>N10025</union>
    <fac>000002010</fac>
    <job>8062</job>
    <pay>RGR</pay>
    <hours>2</hours>
  </Report_Entry>
  <Report_Entry>
    <POSTING-DATE>02292016</POSTING-DATE>
    <pmtdt>2016-02-29-08:00</pmtdt>
    <emp>10025</emp>
    <cc>020107450</cc>
    <union>N10025</union>
    <fac>000002010</fac>
    <job>8062</job>
    <pay>RGR</pay>
    <hours>110.27</hours>
  </Report_Entry>
  <Report_Entry>
    <POSTING-DATE>02292016</POSTING-DATE>
    <pmtdt>2016-02-29-08:00</pmtdt>
    <emp>10025</emp>
    <cc>020107450</cc>
    <union>N10025</union>
    <fac>000002010</fac>
    <job>8062</job>
    <pay>RGR</pay>
    <hours>61.07</hours>
  </Report_Entry>
  <Report_Entry>
    <POSTING-DATE>02292016</POSTING-DATE>
    <pmtdt>2016-02-29-08:00</pmtdt>
    <emp>10025</emp>
    <cc>020107450</cc>
    <union>N10025</union>
    <fac>000002010</fac>
    <job>8062</job>
    <pay>SAL</pay>
    <hours>2.01</hours>
  </Report_Entry>
  <Report_Entry>
    <POSTING-DATE>02292016</POSTING-DATE>
    <pmtdt>2016-02-29-08:00</pmtdt>
    <emp>10058</emp>
    <cc>020107375</cc>
    <union>N10058</union>
    <fac>000002010</fac>
    <job>8085</job>
    <pay>SAL</pay>
    <hours>130</hours>
  </Report_Entry>
  <Report_Entry>
    <POSTING-DATE>02292016</POSTING-DATE>
    <pmtdt>2016-02-29-08:00</pmtdt>
    <emp>10102</emp>
    <cc>020267515</cc>
    <union>N10102</union>
    <fac>000002026</fac>
    <job>8066</job>
    <pay>BLV</pay>
    <hours>31</hours>
  </Report_Entry>
  <Report_Entry>
    <POSTING-DATE>02292016</POSTING-DATE>
    <pmtdt>2016-02-29-08:00</pmtdt>
    <emp>10102</emp>
    <cc>020267515</cc>
    <union>N10102</union>
    <fac>000002026</fac>
    <job>8066</job>
    <pay>SAL</pay>
    <hours>125</hours>
  </Report_Entry>
  <Report_Entry>
    <POSTING-DATE>02292016</POSTING-DATE>
    <pmtdt>2016-02-29-08:00</pmtdt>
    <emp>10102</emp>
    <cc>020267515</cc>
    <union>N10102</union>
    <fac>000002026</fac>
    <job>8066</job>
    <pay>SAL</pay>
    <hours>125</hours>
  </Report_Entry>
  <Report_Entry>
    <POSTING-DATE>02292016</POSTING-DATE>
    <pmtdt>2016-02-29-08:00</pmtdt>
    <emp>10102</emp>
    <cc>020267515</cc>
    <union>N10102</union>
    <fac>000002026</fac>
    <job>8066</job>
    <pay>VOL</pay>
    <hours>15</hours>
  </Report_Entry>
</Report>

Output:

N10025        000002010 8062 RGR 173.34
N10025        000002010 8062 SAL 2.01
N10058        000002010 8085 SAL 130
N10102        000002026 8066 BLV 31
N10102        000002026 8066 SAL 250
N10102        000002026 8066 VOL 15

1

一个完全符合XSLT精神的简短转换(推送式):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:variable name="vT" select="'&#9;'"/>

 <xsl:key name="kEntryByempPay" match="Report_Entry" use="concat(emp,'|',pay)"/>

  <xsl:template match=
  "/*/*[generate-id()=generate-id(key('kEntryByempPay', concat(emp,'|',pay))[1])]">
    <xsl:value-of select="concat(union, $vT, fac, $vT, job, $vT, pay, $vT,
                                 sum(key('kEntryByempPay', concat(emp,'|',pay))/hours),
                                 '&#xA;')"/>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>

当应用于提供的XML文档时:
<Report>
    <Report_Entry>
        <POSTING-DATE>02292016</POSTING-DATE>
        <pmtdt>2016-02-29-08:00</pmtdt>
        <emp>10025</emp>
        <cc>020107450</cc>
        <union>N10025</union>
        <fac>000002010</fac>
        <job>8062</job>
        <pay>RGR</pay>
        <hours>2</hours>
    </Report_Entry>
    <Report_Entry>
        <POSTING-DATE>02292016</POSTING-DATE>
        <pmtdt>2016-02-29-08:00</pmtdt>
        <emp>10025</emp>
        <cc>020107450</cc>
        <union>N10025</union>
        <fac>000002010</fac>
        <job>8062</job>
        <pay>RGR</pay>
        <hours>110.27</hours>
    </Report_Entry>
    <Report_Entry>
        <POSTING-DATE>02292016</POSTING-DATE>
        <pmtdt>2016-02-29-08:00</pmtdt>
        <emp>10025</emp>
        <cc>020107450</cc>
        <union>N10025</union>
        <fac>000002010</fac>
        <job>8062</job>
        <pay>RGR</pay>
        <hours>61.07</hours>
    </Report_Entry>
    <Report_Entry>
        <POSTING-DATE>02292016</POSTING-DATE>
        <pmtdt>2016-02-29-08:00</pmtdt>
        <emp>10025</emp>
        <cc>020107450</cc>
        <union>N10025</union>
        <fac>000002010</fac>
        <job>8062</job>
        <pay>SAL</pay>
        <hours>2.01</hours>
    </Report_Entry>
    <Report_Entry>
        <POSTING-DATE>02292016</POSTING-DATE>
        <pmtdt>2016-02-29-08:00</pmtdt>
        <emp>10058</emp>
        <cc>020107375</cc>
        <union>N10058</union>
        <fac>000002010</fac>
        <job>8085</job>
        <pay>SAL</pay>
        <hours>130</hours>
    </Report_Entry>
    <Report_Entry>
        <POSTING-DATE>02292016</POSTING-DATE>
        <pmtdt>2016-02-29-08:00</pmtdt>
        <emp>10102</emp>
        <cc>020267515</cc>
        <union>N10102</union>
        <fac>000002026</fac>
        <job>8066</job>
        <pay>BLV</pay>
        <hours>31</hours>
    </Report_Entry>
    <Report_Entry>
        <POSTING-DATE>02292016</POSTING-DATE>
        <pmtdt>2016-02-29-08:00</pmtdt>
        <emp>10102</emp>
        <cc>020267515</cc>
        <union>N10102</union>
        <fac>000002026</fac>
        <job>8066</job>
        <pay>SAL</pay>
        <hours>125</hours>
    </Report_Entry>
    <Report_Entry>
        <POSTING-DATE>02292016</POSTING-DATE>
        <pmtdt>2016-02-29-08:00</pmtdt>
        <emp>10102</emp>
        <cc>020267515</cc>
        <union>N10102</union>
        <fac>000002026</fac>
        <job>8066</job>
        <pay>SAL</pay>
        <hours>125</hours>
    </Report_Entry>
    <Report_Entry>
        <POSTING-DATE>02292016</POSTING-DATE>
        <pmtdt>2016-02-29-08:00</pmtdt>
        <emp>10102</emp>
        <cc>020267515</cc>
        <union>N10102</union>
        <fac>000002026</fac>
        <job>8066</job>
        <pay>VOL</pay>
        <hours>15</hours>
    </Report_Entry>
</Report>

所需的、正确的结果已经产生。
N10025  000002010   8062    RGR 173.34
N10025  000002010   8062    SAL 2.01
N10058  000002010   8085    SAL 130
N10102  000002026   8066    BLV 31
N10102  000002026   8066    SAL 250
N10102  000002026   8066    VOL 15

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接