XSLT - сумма каждого атрибута в каждом элементе XML с for-each? - PullRequest
2 голосов
/ 19 сентября 2011

Я новичок во всем, что касается XSLT, и я уже пытался найти его на нескольких форумах, но я до сих пор не нашел фактического решения моей проблемы.

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

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

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

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

Я пытался вложить для каждого цикла, но я не мог понять, как использовать его в этом примере, потому что XSLT не принимает изменяемые переменные, к которым я фактически привык (процедурное программирование).

У кого-нибудь есть простое решение этой проблемы для меня? Заранее спасибо!

1 Ответ

1 голос
/ 19 сентября 2011

Вы можете использовать функцию sum.

Решение XSTL 1.0:

<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="@time"/>

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

        <xsl:value-of select="concat('Total - in: ', sum(Movie/@in), ', out: ', sum(Movie/@out))"/>
    </xsl:template>

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

</xsl:stylesheet>

Вывод:

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

Для группировки используется метод Мюнхена.Ссылка: http://www.jenitennison.com/xslt/grouping/muenchian.html

// - это сокращение от / потомок-или-сам :: узел () /.Например, // para - это сокращение от / lowerndant-or-self :: node () / child :: para и поэтому выберет любой элемент para в документе (даже элемент para, который является элементом документа, будет выбран с помощью // para, поскольку узел элемента документа является дочерним по отношению к корневому узлу);div // para - это сокращение от div / потомок-или-себя :: node () / child :: para, поэтому он будет выбирать всех потомков para потомков div.

Ссылка: http://www.w3.org/TR/xpath/#path-abbrev

...