XSLT - Как использовать group by в этой ситуации? - PullRequest
1 голос
/ 20 сентября 2011

(продолжение этой темы)

Теперь мне нужно знать количество посетителей, сгруппированных по дням, а затем по периодам. Я пытался применить group-by, предложенный Кирилл Полищук , но я могу получить его для группировки только по одному определенному элементу. Теперь мне нужно знать, как применять несколько групп? Например. Сгруппируйте сначала по дню, а затем по периоду.

У меня есть следующий XML:

<Cinema>
    <Day date="15-09-2011" day="Thursday" week="37" in="543" out="543">
        <Movie name="movie1" in="191" out="191">
            <Period time="16:00:00" in="20" out="20"/>
            <Period time="18:00:00" in="71" out="70"/>
            <Period time="20:00:00" in="100" out="101"/>
        </Movie>
        <Movie name="movie2" in="105" out="105">
            <Period time="16:00:00" in="13" out="13"/>
            <Period time="18:00:00" in="34" out="34"/>
            <Period time="20:00:00" in="58" out="58"/>
        </Movie>
        <Movie name="movie3" in="247" out="247">
            <Period time="16:00:00" in="57" out="57"/>
            <Period time="18:00:00" in="75" out="72"/>
            <Period time="20:00:00" in="115" out="118"/>
        </Movie>
    <Day>
    <Day date="16-09-2011" day="Friday" week="37" in="1151" out="1151">
        <Movie name="movie1" in="364" out="364">
            <Period time="16:00:00" in="106" out="106"/>
            <Period time="18:00:00" in="131" out="129"/>
            <Period time="20:00:00" in="127" out="129"/>
        </Movie>
        <Movie name="movie2" in="333" out="333">
            <Period time="16:00:00" in="89" out="89"/>
            <Period time="18:00:00" in="116" out="116"/>
            <Period time="20:00:00" in="128" out="128"/>
        </Movie>
        <Movie name="movie3" in="454" out="454">
            <Period time="16:00:00" in="104" out="104"/>
            <Period time="18:00:00" in="150" out="150"/>
            <Period time="20:00:00" in="200" out="200"/>
        </Movie>
    <Day>
</Cinema>

То, что я пытаюсь получить, - это общее количество посетителей каждого периода фильма в день. Например:

Thursday:
16:00h - in: 90, out: 90
18:00h - in: 180, out: 176
20:00h - in: 273, out: 277
Total - in: 543, out: 543

Friday: 
16:00h - in: 299, out: 299
18:00h - in: 397, out: 395
20:00h - in: 455, out: 457
Total - in: 1151, out: 1151

У кого-нибудь есть предложения? Заранее спасибо!

(на данный момент я использую xslt 1.0, но при необходимости я могу «обновиться» до более новой версии 2.0)

1 Ответ

0 голосов
/ 20 сентября 2011
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:key name="k" match="Period" use="concat(../../@date, @time)"/>

    <xsl:template match="/Cinema">
        <xsl:apply-templates select="Day"/>
    </xsl:template>

    <xsl:template match="Day">
        <xsl:value-of select="concat(@day, ':')"/>
        <xsl:text>&#xA;</xsl:text>

        <xsl:apply-templates select="*/Period[generate-id(.) = generate-id(key('k', concat(../../@date, @time)))]"/>

        <xsl:value-of select="concat('Total - in: ', @in, ', out: ', @out)"/>
        <xsl:text>&#xA;&#xA;</xsl:text>
    </xsl:template>

    <xsl:template match="Period">
        <xsl:value-of select="
                      concat(substring(@time, 1, 5), 'h - in: ', 
                        sum(key('k', concat(../../@date, @time))/@in), 
                        ', out: ', 
                        sum(key('k', concat(../../@date, @time))/@out))"/>
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>

</xsl:stylesheet>

XML:

<Cinema>
    <Day date="15-09-2011" day="Thursday" week="37" in="543" out="543">
        <Movie name="movie1" in="191" out="191">
            <Period time="16:00:00" in="20" out="20"/>
            <Period time="18:00:00" in="71" out="70"/>
            <Period time="20:00:00" in="100" out="101"/>
        </Movie>
        <Movie name="movie2" in="105" out="105">
            <Period time="16:00:00" in="13" out="13"/>
            <Period time="18:00:00" in="34" out="34"/>
            <Period time="20:00:00" in="58" out="58"/>
        </Movie>
        <Movie name="movie3" in="247" out="247">
            <Period time="16:00:00" in="57" out="57"/>
            <Period time="18:00:00" in="75" out="72"/>
            <Period time="20:00:00" in="115" out="118"/>
        </Movie>
    </Day>
    <Day date="16-09-2011" day="Friday" week="37" in="1151" out="1151">
        <Movie name="movie1" in="364" out="364">
            <Period time="16:00:00" in="106" out="106"/>
            <Period time="18:00:00" in="131" out="129"/>
            <Period time="20:00:00" in="127" out="129"/>
        </Movie>
        <Movie name="movie2" in="333" out="333">
            <Period time="16:00:00" in="89" out="89"/>
            <Period time="18:00:00" in="116" out="116"/>
            <Period time="20:00:00" in="128" out="128"/>
        </Movie>
        <Movie name="movie3" in="454" out="454">
            <Period time="16:00:00" in="104" out="104"/>
            <Period time="18:00:00" in="150" out="150"/>
            <Period time="20:00:00" in="200" out="200"/>
        </Movie>
    </Day>
</Cinema>

Вывод:

Thursday:
16:00h - in: 90, out: 90
18:00h - in: 180, out: 176
20:00h - in: 273, out: 277
Total - in: 543, out: 543

Friday:
16:00h - in: 299, out: 299
18:00h - in: 397, out: 395
20:00h - in: 455, out: 457
Total - in: 1151, out: 1151
...