需要基于2个元素对节点进行分组,并对第三个元素求和。键?变量?

时间:2016-06-09 18:25:25

标签: xml xslt xpath

提前感谢您的帮助 我有一个大的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>  

我想要的输出是每个emp / pay组合的单行,相关的小时数总计为:

      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>

2 个答案:

答案 0 :(得分:0)

使用 Muenchian方法

XSLT 1.0:

<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>

<强>输出

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 :(得分:0)

完全符合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