XSLT应该只处理具有相同日期的节点一次

时间:2015-04-20 14:06:18

标签: xslt xslt-1.0

我正在寻找XSLT,在遍历xml文件时只对具有相同日期的数量求和一次。

输入:

<root>
  <interval>
    <mn>
        <quantity>1</quantity>
        <date>2015-03-14</date>
        <ccode>102010</ccode>
    </mn>
    <mn>
        <quantity>2</quantity>
        <date>2015-03-15</date>
        <ccode>202010</ccode>
    </mn>
  </interval>
  <interval>
    <mn>
        <quantity>1</quantity>
        <date>2015-03-15</date>
        <ccode>202000</ccode>
    </mn>
    <mn>
        <quantity>2</quantity>
        <date>2015-03-17</date>
        <ccode>302010</ccode>
    </mn>
  </interval>
  <interval>
    <mn>
        <quantity>5</quantity>
        <date>2015-03-14</date>
        <ccode>102000</ccode>
    </mn>
    <mn>
        <quantity>3</quantity>
        <date>2015-03-18</date>
        <ccode>402010</ccode>
    </mn>
  </interval>
</root>

预期产出:

    <mn>
        <quantity>6</quantity>
        <date>2015-03-14</date>
        <ccode>102000</ccode>
    </mn>
    <mn>
        <quantity>3</quantity>
        <date>2015-03-15</date>
        <ccode>202000</ccode>
    </mn>
    <mn>
        <quantity>2</quantity>
        <date>2015-03-17</date>
        <ccode>302010</ccode>
    </mn>
    <mn>
        <quantity>3</quantity>
        <date>2015-03-18</date>
        <ccode>402010</ccode>
    </mn>

日期匹配时添加数量。我的xslt问题是它遍历第一个间隔节点中的每个mn节点,从所有间隔节点汇总相同日期的数量,然后它遍历第二个间隔并“再次从所有间隔节点”汇总数量。我只希望一个日期的数量总和一次。 CCODE值应该是日期的所有值的最小值/最小值。 我的XSLT如下:

    <xsl:template match="/">    
    <xsl:for-each select="root/interval/mn">      
    <xsl:variable name="dtt" select="date"/>      
        <xsl:variable name="qty" select="sum(../../interval/mn[date = $dtt]/quantity)"/>
    </xsl:for-each>

1 个答案:

答案 0 :(得分:2)

你大部分都在那里 - 只需要使用Muenchian分组(定义{{​​1}})让你的xsl:key只选择一个日期节点一次。

XSLT:

for-each

输出:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="mnByDate" match="mn" use="date" />
    <xsl:template match="/">  
        <root> 
            <xsl:for-each select="root/interval/mn[count(. | key('mnByDate', date)[1]) = 1]">      
                <xsl:variable name="dtt" select="date"/>      
                <xsl:variable name="ccode" select="ccode"/>      
                <xsl:variable name="qty" select="sum(../../interval/mn[date = $dtt]/quantity)"/>
                <mn>
                    <quantity>
                        <xsl:value-of select="$qty"/>
                    </quantity>
                    <date>
                        <xsl:value-of select="$dtt" />
                    </date>
                    <ccode>
                        <xsl:value-of select="//mn[date = $dtt]/ccode[not(. > //mn[date = $dtt]/ccode)][1]" />
                    </ccode>
                </mn>
            </xsl:for-each>
        </root>
    </xsl:template>
</xsl:stylesheet>