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

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

最佳答案

您已经完成了大部分工作 - 只需使用 Muenchian 分组(定义一个 xsl:key)让您的 for-each 仅选择每个日期节点一次.

XSLT:

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

输出:

<?xml version="1.0" encoding="utf-8"?>
<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>
</root>

关于XSLT 应该只处理具有相同日期的节点一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29750186/

相关文章:

xml - 同时复制结构和子结构

xslt - XSL : Find text not currently in elements and wrap?

xslt - <key> 元素中的 key() 函数

xslt - 将 2 个数字相乘,然后求和

XSLT 1.0 贪婪背包分组方法?

java - PHSchematron 无法验证 `p` 元素内包含 `pattern` 元素的 schematron 文件

json - JSON 的 XSLT 等效项

xml - XSLT 2.0 : Substring-after on a for-each loop to get distinct-values

xml - 静态内容但动态内容中的 XSL-FO 页脚?

xpath - 使用正则表达式模式检查 XML 元素的属性值