开发者

XSLT - Sum of each attribute in every element in XML with for-each?

开发者 https://www.devze.com 2023-04-06 00:15 出处:网络
I am new to the whole XSLT thing and I\'ve already tried looking it up through several forums, but I still haven\'t found the actual solution to my problem.

I am new to the whole XSLT thing and I've already tried looking it up through several forums, but I still haven't found the actual solution to my problem.

I have the following 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"/>
        <Per开发者_C百科iod 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>

What I am trying to get is the total visitors of each movie period. For example:

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

I tried nested for each loops but I couldn't really figure out how to use it in this kind of example, because XSLT doesn't accept changeable variables, which I am actually used to (procedural programming).

Does anyone have a simple solution to this problem for me? Thanks in advance!


You can use sum function.

XSTL 1.0 solution:

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

Output:

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

It uses Muenchian method for grouping. Reference: http://www.jenitennison.com/xslt/grouping/muenchian.html

// is short for /descendant-or-self::node()/. For example, //para is short for /descendant-or-self::node()/child::para and so will select any para element in the document (even a para element that is a document element will be selected by //para since the document element node is a child of the root node); div//para is short for div/descendant-or-self::node()/child::para and so will select all para descendants of div children.

Reference: http://www.w3.org/TR/xpath/#path-abbrev

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号