Xml XSLT1.0使用两个标准对值进行分组

Xml XSLT1.0使用两个标准对值进行分组,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我有以下XML: <test> <itemGroup> <item> <date>20151020</date> <time>1201</time> <amount>1.000</amount> </item> <it

我有以下XML:

<test>                               
   <itemGroup>        
    <item>
        <date>20151020</date>
        <time>1201</time>
        <amount>1.000</amount>
    </item>
    <item>
        <date>20151020</date>
        <time>1202</time>
        <amount>1.000</amount>
    </item>
    <item>
        <date>20151020</date>
        <time>1203</time>
        <amount>1.000</amount>
    </item>
    <item>
        <date>20151020</date>
        <time>1204</time>
        <amount>1.000</amount>
    </item>
    <item>
        <date>20151020</date>
        <time>1205</time>
        <amount>1.000</amount>
    </item>

    <item>
        <date>20151021</date>
        <time>1301</time>
        <amount>1.000</amount>
    </item>
    <item>
        <date>20151021</date>
        <time>1302</time>
        <amount>1.000</amount>
    </item>
    <item>
        <date>20151021</date>
        <time>1303</time>
        <amount>1.000</amount>
    </item>
    <item>
        <date>20151021</date>
        <time>1304</time>
        <amount>1.000</amount>
    </item>
    <item>
        <date>20151021</date>
        <time>1305</time>
        <amount>1.000</amount>
    </item>

</itemGroup>
<itemGroup>        
    <item>                        
        <date>20151022</date>
        <time>1047</time>
        <amount>1.000</amount>
    </item>
    <item>
        <date>20151022</date>
        <time>1147</time>
        <amount>1.000</amount>
    </item>                
    <item>
        <date>20151022</date>
        <time>1247</time>
        <amount>1.000</amount>
    </item>                    
</itemGroup>
<itemGroup>      
    <item>
        <date>20151020</date>
        <time>2211</time>
        <amount>1.000</amount>
    </item>
    <item>
        <date>20151020</date>
        <time>2222</time>
        <amount>1.000</amount>
    </item>                   
</itemGroup>                
</test>

20151020
1201
1
20151020
1202
1
20151020
1203
1
20151020
1204
1
20151020
1205
1
20151021
1301
1
20151021
1302
1
20151021
1303
1
20151021
1304
1
20151021
1305
1
20151022
1047
1
20151022
1147
1
20151022
1247
1
20151020
2211
1
20151020
2222
1
以及以下XSLT:

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

<xsl:template match="test">
    <Main>          
        <xsl:apply-templates select="itemGroup"/>           
    </Main>     
</xsl:template>

<xsl:template match="itemGroup">
    <xsl:comment>** item Group #<xsl:value-of select="position()"/></xsl:comment>

    <xsl:variable name="Max_Size">3</xsl:variable>

    <xsl:comment>item count : <xsl:value-of select="count(item)"/></xsl:comment>
    <xsl:comment> </xsl:comment>

    <xsl:for-each select="item[ position() mod $Max_Size = 1 or (not(date=preceding-sibling::item/date) and not(position() mod $Max_Size = 1)) ]">
        <xsl:comment>** Header <xsl:value-of select="position()"/> </xsl:comment>

        <segment name="Header">
            <xsl:attribute name="nb"><xsl:value-of select="position()"/></xsl:attribute>
            <element name="date"><xsl:value-of select="date"/></element>
            <element name="sum"><xsl:value-of select="format-number(sum(../item/amount), '0')"/></element><!--sum of all amount of this group-->                
        </segment>

        <xsl:for-each select=".|following-sibling::item[position() &lt; $Max_Size and date=preceding-sibling::item/date]">              
            <segment name="item">                   
                <element name="time"><xsl:value-of select="time"/></element>
            </segment>              
        </xsl:for-each>

    </xsl:for-each>

</xsl:template>
</xsl:stylesheet>

**项目组#
3.
项目计数:
**标题
我得到的结果是:

<Main>
<!--** item Group #1-->
<!--item count : 10-->
<!---->
<!--** Header 1-->
<segment name="Header" nb="1">
    <element name="date">20151020</element>
    <element name="sum">10</element>
</segment>
<segment name="item">
    <element name="time">1201</element>
</segment>
<segment name="item">
    <element name="time">1202</element>
</segment>
<segment name="item">
    <element name="time">1203</element>
</segment>
<!--** Header 2-->
<segment name="Header" nb="2">
    <element name="date">20151020</element>
    <element name="sum">10</element>
</segment>
<segment name="item">
    <element name="time">1204</element>
</segment>
<segment name="item">
    <element name="time">1205</element>
</segment>
<!--** Header 3-->
<segment name="Header" nb="3">
    <element name="date">20151021</element>
    <element name="sum">10</element>
</segment>
<segment name="item">
    <element name="time">1301</element>
</segment>
<segment name="item">
    <element name="time">1302</element>
</segment>
<segment name="item">
    <element name="time">1303</element>
</segment>
<!--** Header 4-->
<segment name="Header" nb="4">
    <element name="date">20151021</element>
    <element name="sum">10</element>
</segment>
<segment name="item">
    <element name="time">1302</element>
</segment>
<segment name="item">
    <element name="time">1303</element>
</segment>
<segment name="item">
    <element name="time">1304</element>
</segment>
<!--** Header 5-->
<segment name="Header" nb="5">
    <element name="date">20151021</element>
    <element name="sum">10</element>
</segment>
<segment name="item">
    <element name="time">1305</element>
</segment>
<!--** item Group #2-->
<!--item count : 3-->
<!---->
<!--** Header 1-->
<segment name="Header" nb="1">
    <element name="date">20151022</element>
    <element name="sum">3</element>
</segment>
<segment name="item">
    <element name="time">1047</element>
</segment>
<segment name="item">
    <element name="time">1147</element>
</segment>
<segment name="item">
    <element name="time">1247</element>
</segment>
<!--** item Group #3-->
<!--item count : 2-->
<!---->
<!--** Header 1-->
<segment name="Header" nb="1">
    <element name="date">20151020</element>
    <element name="sum">2</element>
</segment>
<segment name="item">
    <element name="time">2211</element>
</segment>
<segment name="item">
    <element name="time">2222</element>
</segment>
</Main>

20151020
10
1201
1202
1203
20151020
10
1204
1205
20151021
10
1301
1302
1303
20151021
10
1302
1303
1304
20151021
10
1305
20151022
3.
1047
1147
1247
20151020
2.
2211
2222
我想要实现的是根据这些标准对值进行分组

1-同一日期的所有项目。 2-组大小不得超过“最大大小”(3),应改为启动新组

我能够分别达到这两个标准,但当试图将它们结合在一起时,它停止了工作

可选奖金问题:总金额仅为当前组的金额

我必须使用1.0

以下是我期望的结果:

<Main>
<!--** item Group #1-->
<!--item count : 10-->
<!---->
<!--** Header 1-->
<segment name="Header" nb="1">
    <element name="date">20151020</element>
    <element name="sum">3</element>
</segment>
<segment name="item">
    <element name="time">1201</element>
</segment>
<segment name="item">
    <element name="time">1202</element>
</segment>
<segment name="item">
    <element name="time">1203</element>
</segment>
<!--** Header 2-->
<segment name="Header" nb="2">
    <element name="date">20151020</element>
    <element name="sum">3</element>
</segment>
<segment name="item">
    <element name="time">1204</element>
</segment>
<segment name="item">
    <element name="time">1205</element>
</segment>
<!--** Header 3-->
<segment name="Header" nb="3">
    <element name="date">20151021</element>
    <element name="sum">3</element>
</segment>
<segment name="item">
    <element name="time">1301</element>
</segment>
<segment name="item">
    <element name="time">1302</element>
</segment>
<segment name="item">
    <element name="time">1303</element>
</segment>
<!--** Header 4-->
<segment name="Header" nb="4">
    <element name="date">20151021</element>
    <element name="sum">2</element>
</segment>    
<segment name="item">
    <element name="time">1304</element>
</segment>
<segment name="item">
    <element name="time">1305</element>
</segment>    
<!--** item Group #2-->
<!--item count : 3-->
<!---->
<!--** Header 1-->
<segment name="Header" nb="1">
    <element name="date">20151022</element>
    <element name="sum">3</element>
</segment>
<segment name="item">
    <element name="time">1047</element>
</segment>
<segment name="item">
    <element name="time">1147</element>
</segment>
<segment name="item">
    <element name="time">1247</element>
</segment>
<!--** item Group #3-->
<!--item count : 2-->
<!---->
<!--** Header 1-->
<segment name="Header" nb="1">
    <element name="date">20151020</element>
    <element name="sum">2</element>
</segment>
<segment name="item">
    <element name="time">2211</element>
</segment>
<segment name="item">
    <element name="time">2222</element>
</segment>
</Main>

20151020
3.
1201
1202
1203
20151020
3.
1204
1205
20151021
3.
1301
1302
1303
20151021
2.
1304
1305
20151022
3.
1047
1147
1247
20151020
2.
2211
2222

这部分是一个分组问题,在XSLT1.0中,可以使用名为

在给定的
itemGroup
中,您按日期对
item
元素进行分组,因此您可以这样定义一个键

<xsl:key name="items" match="item" use="concat(generate-id(..), '|', date)" />
但是你需要选择3人一组,这就增加了复杂性。你可以用这种可怕的表情来表达:

<xsl:for-each 
     select="item[count(. | key('items', concat(generate-id(..), '|', date))[position() mod $Max_Size = 1]) 
                  = ceiling(count(key('items', concat(generate-id(..), '|', date))) div $Max_Size)]">

然后,组中的项目定义如下:

<xsl:variable name="group" select=".|following-sibling::item[position() &lt; $Max_Size and date = current()/date]" />

试试这个XSLT

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

<xsl:key name="items" match="item" use="concat(generate-id(..), '|', date)" />

<xsl:template match="test">
    <Main>   
        <xsl:apply-templates select="itemGroup"/>           
    </Main>     
</xsl:template>

<xsl:template match="itemGroup">
    <xsl:comment>** item Group #<xsl:value-of select="position()"/></xsl:comment>

    <xsl:variable name="Max_Size">3</xsl:variable>

    <xsl:comment>item count : <xsl:value-of select="count(item)"/></xsl:comment>
    <xsl:comment> </xsl:comment>
    <xsl:for-each select="item[count(. | key('items', concat(generate-id(..), '|', date))[position() mod $Max_Size = 1]) = ceiling(count(key('items', concat(generate-id(..), '|', date))) div $Max_Size)]">
        <xsl:comment>** Header <xsl:value-of select="position()"/> </xsl:comment>

        <xsl:variable name="group" select=".|following-sibling::item[position() &lt; $Max_Size and date = current()/date]" />
        <segment name="Header">
            <xsl:attribute name="nb"><xsl:value-of select="position()"/></xsl:attribute>
            <element name="date"><xsl:value-of select="date"/></element>
            <element name="sum"><xsl:value-of select="format-number(sum($group/amount), '0')"/></element><!--sum of all amount of this group-->                
        </segment>

        <xsl:for-each select="$group">              
            <segment name="item">                   
                <element name="time"><xsl:value-of select="time"/></element>
            </segment>              
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

**项目组#
3.
项目计数:
**标题

这部分是一个分组问题,在XSLT1.0中,可以使用名为

在给定的
itemGroup
中,您按日期对
item
元素进行分组,因此您可以这样定义一个键

<xsl:key name="items" match="item" use="concat(generate-id(..), '|', date)" />
但是你需要选择3人一组,这就增加了复杂性。你可以用这种可怕的表情来表达:

<xsl:for-each 
     select="item[count(. | key('items', concat(generate-id(..), '|', date))[position() mod $Max_Size = 1]) 
                  = ceiling(count(key('items', concat(generate-id(..), '|', date))) div $Max_Size)]">

然后,组中的项目定义如下:

<xsl:variable name="group" select=".|following-sibling::item[position() &lt; $Max_Size and date = current()/date]" />

试试这个XSLT

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

<xsl:key name="items" match="item" use="concat(generate-id(..), '|', date)" />

<xsl:template match="test">
    <Main>   
        <xsl:apply-templates select="itemGroup"/>           
    </Main>     
</xsl:template>

<xsl:template match="itemGroup">
    <xsl:comment>** item Group #<xsl:value-of select="position()"/></xsl:comment>

    <xsl:variable name="Max_Size">3</xsl:variable>

    <xsl:comment>item count : <xsl:value-of select="count(item)"/></xsl:comment>
    <xsl:comment> </xsl:comment>
    <xsl:for-each select="item[count(. | key('items', concat(generate-id(..), '|', date))[position() mod $Max_Size = 1]) = ceiling(count(key('items', concat(generate-id(..), '|', date))) div $Max_Size)]">
        <xsl:comment>** Header <xsl:value-of select="position()"/> </xsl:comment>

        <xsl:variable name="group" select=".|following-sibling::item[position() &lt; $Max_Size and date = current()/date]" />
        <segment name="Header">
            <xsl:attribute name="nb"><xsl:value-of select="position()"/></xsl:attribute>
            <element name="date"><xsl:value-of select="date"/></element>
            <element name="sum"><xsl:value-of select="format-number(sum($group/amount), '0')"/></element><!--sum of all amount of this group-->                
        </segment>

        <xsl:for-each select="$group">              
            <segment name="item">                   
                <element name="time"><xsl:value-of select="time"/></element>
            </segment>              
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

**项目组#
3.
项目计数:
**标题

“1-同一日期的所有项目。”这不是您的输出显示的内容。开始时有两个组(3+2项)的日期为20151020,结束时有另一个组的日期为同一日期(2项)。是的,很抱歉,每个项目组(来自原始xml)都是不同的项目,因此它们可以并且将具有重叠的日期。itemGroup应该单独处理。“1-同一日期的所有项目。”这不是您的输出所显示的。开始时有两个组(3+2项)的日期为20151020,结束时有另一个组的日期为同一日期(2项)。是的,很抱歉,每个项目组(来自原始xml)都是不同的项目,因此它们可以并且将具有重叠的日期。所有项目组都应该单独处理。这不是假设项目在每个组内进行排序吗?我确认数据应该在每个组内进行排序。我仍然有兴趣知道如何使用sort()函数解析未排序的项目?@JimCusler处理未排序项目的问题不是“解析”。将他们分成3人一组比较困难,因为组中的成员不一定是相邻的兄弟姐妹。处理此问题的一种方法是将转换分为两个过程,以便第二个过程中的子分组处理连续的组。这不是假设项目在每个组中排序吗?我确认数据预期在每个组中排序。我仍然有兴趣知道如何使用sort()函数解析未排序的项目?@JimCusler处理未排序项目的问题不是“解析”。将他们分成3人一组比较困难,因为组中的成员不一定是相邻的兄弟姐妹。处理这个问题的一种方法是将转换分为两个过程,以便第二个过程中的子分组处理连续组。