Ticketer: Difference between revisions

From ICO wiki
Jump to navigationJump to search
Line 613: Line 613:
</source>
</source>


===XSLT 3===
===XSLT 3 (xml)===


<source lang="xml">
<source lang="xml">

Revision as of 15:07, 20 March 2017

Meeskond

Liina Abner
Krista Rüütel
Roland Türi

Idee

Projekt

XML

Teema

XML

<?xml version="1.0" encoding="utf-8" ?>

<Events>
  <Categories>
    <Category id="24" lang="est">Muusika</Category>
    <Category id="24" lang="eng">Music</Category>
    <Category id="24" lang="rus">Музыка</Category>
    <Category id="25" lang="est">Kogupere</Category>
    <Category id="25" lang="eng">Family</Category>
    <Category id="25" lang="rus">Для семьи</Category>
    <Category id="26" lang="est">Filmid</Category>
    <Category id="26" lang="eng">Movies</Category>
    <Category id="26" lang="rus">Кино</Category>
    <Category id="27" lang="est">Teater</Category>
    <Category id="27" lang="eng">Theatre</Category>
    <Category id="27" lang="rus">Театр</Category>
    <Category id="28" lang="est">Sport</Category>
    <Category id="28" lang="eng">Sport</Category>
    <Category id="28" lang="rus">Спорт</Category>
  </Categories>
  <Municipalities>
    <Municipality id="1" country="est">Harjumaa</Municipality>
    <Municipality id="2" country="est">Tartumaa</Municipality>
    <Municipality id="3" country="est">Ida-Virumaa</Municipality>
    <Municipality id="4" country="est">Pärnumaa</Municipality>
    <Municipality id="5" country="est">Lääne-Virumaa</Municipality>
    <Municipality id="6" country="est">Viljandimaa</Municipality>
    <Municipality id="7" country="est">Raplamaa</Municipality>
    <Municipality id="8" country="est">Võrumaa</Municipality>
    <Municipality id="9" country="est">Saaremaa</Municipality>
    <Municipality id="10" country="est">Jõgevamaa</Municipality>
    <Municipality id="11" country="est">Järvamaa</Municipality>
    <Municipality id="12" country="est">Valgamaa</Municipality>
    <Municipality id="13" country="est">Põlvamaa</Municipality>
    <Municipality id="14" country="est">Läänemaa</Municipality>
    <Municipality id="15" country="est">Hiiumaa</Municipality>
  </Municipalities>
  <Event id="1">
    <EventContent id="38">
      <Title>
        <![CDATA[Eesti meistrivõistlused korvpallis. Finaal.]]>
      </Title>
      <Categories>
        <Category id="28" />
        <Category id="25" />
      </Categories>
      <Description lang="EST"><![CDATA[Ela kaasa aasta tähtsündmusele. Unustamatu pallilahing.]]></Description>
      <ImageUrl>https://upload.wikimedia.org/wikipedia/commons/8/87/Gergati.jpg</ImageUrl>
      <Performers>
        <Performer><![CDATA[Kalev Cramo]]></Performer>
        <Performer><![CDATA[TÜ Rock]]></Performer>
      </Performers>
    </EventContent>
    <StartTime type="ISO 8601">15-04-2017T14:00+03:00</StartTime>
    <DurationInMinutes>90</DurationInMinutes>
    <Venue id="10" country="EST" municipality_id="1" capacity="200">
      <Name><![CDATA[Saku Suurhall]]></Name>
      <Description lang="est"><![CDATA[Avar ja kaunis Haabersti spordipalee. Eesti suurim multifunktsionaalne areen.]]></Description>
      <Description lang="eng"><![CDATA[Big big hall]]></Description>
      <Location lat="59.5467" lng="26.1830"/>
    </Venue>
    <PriceInfo>
      <Price min="10.00" max="25.00" />
    </PriceInfo>
  </Event>
  <Event id="2">
    <EventContent id="39">
      <Title>
        <![CDATA[Jaak Joala laulud]]>
      </Title>
      <Categories>
        <Category id="24" />
        <Category id="25" />
      </Categories>
      <Description lang="EST"><![CDATA[Kaunid laulud romantikasõpradele.]]></Description>
      <ImageUrl>https://www.rahvaraamat.ee/images/products/000/732/006/thumbnails/big/f1e93bcba84cc8826368227093a41c5f1212230d/jaak-joala-kuulsuse-ahelad.jpg</ImageUrl>
      <Performers>
        <Performer role="singer"><![CDATA[Koit Toome]]></Performer>
        <Performer role="singer"><![CDATA[Birgit Sarrap]]></Performer>
      </Performers>
    </EventContent>
    <StartTime type="ISO 8601">02-04-2017T14:00+03:00</StartTime>
    <DurationInMinutes>90</DurationInMinutes>
    <Venue id="10" country="EST" municipality_id="5" capacity="200">
      <Name><![CDATA[Vihula mõis]]></Name>
      <Description lang="est"><![CDATA[Eesti üks kauneimaid häärbereid metsade keskel.]]></Description>
      <Description lang="eng"><![CDATA[Beautiful Estonian manor house]]></Description>
      <Location lat="59.4260" lng="24.6474"/>
    </Venue>
    <PriceInfo>
      <Price min="5.00" max="15.00" />
    </PriceInfo>
  </Event>
  <Event id="3">
    <EventContent id="40">
      <Title>
        <![CDATA[TRAD.ATTACK! - uue albumi ''KULLAKARVA'' esitluskontsert]]>
      </Title>
      <Categories>
        <Category id="24" />
        <Category id="25" />
      </Categories>
      <Description lang="EST"><![CDATA[Maikuus ilmub ülemaailmselt Trad.Attack!'i uus album “Kullakarva”. Albumi esitlustuur viib bändi esinema paljudesse riikidesse nii Euroopas kui mujal maailmas ning rõõmu uuest muusikast jagab bänd loomulikult ka kodumaise publikuga!]]></Description>
      <ImageUrl>http://www.piletilevi.ee/imageGenerator/778eb6184f8ef9ff50e5fc3e84e9a801/eventDetails</ImageUrl>
      <Performers>
        <Performer role="singer"><![CDATA[Sandra Vabarna]]></Performer>
        <Performer role="singer"><![CDATA[Jalmar Vabarna]]></Performer>
        <Performer role="musician"><![CDATA[Tõnu Tubli]]></Performer>
      </Performers>
    </EventContent>
    <StartTime type="ISO 8601">30-06-2017T16:00+03:00</StartTime>
    <DurationInMinutes>120</DurationInMinutes>
    <Venue id="11" country="EST" municipality_id="1" capacity="300">
      <Name><![CDATA[Vaba Lava]]></Name>
      <Description lang="est"><![CDATA[Vaba Lava eesmärgiks kujuneda etenduskunstide valdkonna produktsoonikeskuseks ja loomeinkubaatoriks ning laiendada rahvusvahelist areaali, andes oma panuse nii kultuurieksporti kui -importi.]]></Description>
      <Description lang="eng"><![CDATA[Vaba Lava wishes to become a venue for young, experimental and innovative performing arts and network with theatres with similar profiles abroad.]]></Description>
      <Location lat="59.2623" lng="24.4344"/>
    </Venue>
    <PriceInfo>
      <Price min="16.00" max="79.00" />
    </PriceInfo>
  </Event>
  <Event id="4">
    <EventContent id="41">
      <Title>
        <![CDATA[Popi ja Huhuu]]>
      </Title>
      <Categories>
        <Category id="27" />
      </Categories>
      <Description lang="EST">
        <![CDATA[Tuglase lihtne kuid sümbolistlik lugu üllatab oma mitmekihilisuse ja ajatusega ning on praegugi teravalt päevakajaline. Tegemist on harukordse novelliga, mis pakub teatrile avaraid loomingulisi võimalusi. Pea sõnatu materjal tõlgituna universaalsesse teatrikeelde, võimaldab nukkude ja maskide, valguste ja varjude ning helide ja vaikustega luua maailma, mis on vaatajale mõistetav ja tajutav sõltumata riigipiirist või keelebarjäärist.]]>
      </Description>
      <ImageUrl>http://www.piletilevi.ee/imageGenerator/286dd7f573c4ec7b7543fbf2efbad714/eventDetails</ImageUrl>
      <Performers>
        <Performer role="producer"><![CDATA[Leino Rei]]></Performer>
        <Performer role="actor"><![CDATA[Tarmo Song]]></Performer>
        <Performer role="actor"><![CDATA[Mirko Rajas]]></Performer>
        <Performer role="actor"><![CDATA[Helvin Kaljula]]></Performer>
      </Performers>
    </EventContent>
    <StartTime type="ISO 8601">10-04-2017T16:00+03:00</StartTime>
    <DurationInMinutes>105</DurationInMinutes>
    <Venue id="12" country="EST" municipality_id="1" capacity="150">
      <Name><![CDATA[Eesti Draamateater]]></Name>
      <Description lang="est"><![CDATA[Eesti Draamateater on Eesti suurim sõnateater, praegu on siin 37 näitlejaga püsitrupp ja 4 koosseisulist lavastajat. Igal hooajal on teatris kümmekond esietendust, jooksvas repertuaaris on üle 20 lavastuse. Aasta jooksul annab Eesti Draamateater ligi 500 etendust ja neid vaatab üle 100 000 vaataja.]]></Description>
      <Description lang="eng"><![CDATA[The Estonian Drama Theatre is the biggest verbal theatre in Estonia; at the moment the permanent troupe consists of 37 actors and actresses and there are 5 permanent directors. Around 10 plays premier every season and more than 20 plays are constantly in the repertoire. During one year almost 500 performances are given and more than 100,000 people come to see the plays.]]></Description>
      <Location lat="59.4347" lng="24.7489"/>
    </Venue>
    <PriceInfo>
      <Price min="15.00" max="18.00" />
    </PriceInfo>
  </Event>
  <Event id="5">
    <EventContent id="42">
      <Title>
        <![CDATA[Furby tagasitulek]]>
      </Title>
      <Categories>
        <Category id="25" />
        <Category id="27" />
      </Categories>
      <Description lang="EST">
        <![CDATA[Kas sa tunned, et oled vahel väsinud? Ja see pole see väsimus, mis tekib peale väikest sörki metsarajal. See pole ka lihtsalt mingi meeldiv rammestus eduka tööpäeva lõpul. Vaid see on selline perekondlik väsimus, mis tekib siis, kui laste mahaaetud puder täidab põrandalaudade vahesid, kui lõppevad puhtad sokid, kui enam ei jõua kedagi kuulata, kui ainsad teemad naisega on sina tood, mina viin. Ehk lahendaks pagulased palju meie koduseid ja isiklikke, ehk ka intiimseid probleeme? Sest tööd on alati kuhjaga, aega ja raha, tähelepanu ja armastust aga vähe, üks inimene kuluks ära küll. Või siis ikkagi ei ole meil teda vaja? Kas meil üldse on teisi inimesi vaja? Kas meil on võimalik teistest inimestest aru saada? Endastki on raske aru saada. Neile küsimustele püüabki vastuseid leida Urmas Vadi lavastus "Furby tagasitulek".]]>
      </Description>
      <ImageUrl>http://www.piletilevi.ee/imageGenerator/798a6ac2db0d64faa3ce50e31106a1a9/eventDetails</ImageUrl>
      <Performers>
        <Performer role="producer"><![CDATA[Urmas Vadi]]></Performer>
        <Performer role="actor"><![CDATA[Liina Vahtrik]]></Performer>
        <Performer role="actor"><![CDATA[Aarne Soro]]></Performer>
        <Performer role="actor"><![CDATA[Peeter Rästas]]></Performer>
      </Performers>
    </EventContent>
    <StartTime type="ISO 8601">18-05-2017T15:00+03:00</StartTime>
    <DurationInMinutes>90</DurationInMinutes>
    <Venue id="11" country="EST" municipality_id="1" capacity="300">
      <Name><![CDATA[Vaba Lava]]></Name>
      <Description lang="est"><![CDATA[Vaba Lava eesmärgiks kujuneda etenduskunstide valdkonna produktsoonikeskuseks ja loomeinkubaatoriks ning laiendada rahvusvahelist areaali, andes oma panuse nii kultuurieksporti kui -importi.]]></Description>
      <Description lang="eng"><![CDATA[Vaba Lava wishes to become a venue for young, experimental and innovative performing arts and network with theatres with similar profiles abroad.]]></Description>
      <Location lat="59.2623" lng="24.4344"/>
    </Venue>
    <PriceInfo>
      <Price min="14.00" max="18.00" />
    </PriceInfo>
  </Event>
  <Event id="6">
    <EventContent id="43">
      <Title>
        <![CDATA[Vägi]]>
      </Title>
      <Categories>
        <Category id="27" />
      </Categories>
      <Description lang="EST">
        <![CDATA[Lavastus kohanemisest ja traditsioonidest.
            Mismoodi paistavad inimese elu ja tema uskumused kõrvalt vaadates?
            Mis saab teadmistest ja oskustest, kui nendest saab ajalugu, eksponaat vitriinis?
            Mida loevad uskumused ja tavad, kui selle taga pole enam kogemust?
            Kuidas ahistavad inimese elu tavad, millel pole enam aluspõhja?
            Mis saab väest, kui sellega ei oska enam midagi teha?
            Lavastus on loodud spetsiaalselt Eesti Rahva Muuseumi saalis mängimiseks.
            Lavastus moodustab muuseumi ekspositsiooniga omaette terviku, kuid on mõistetav ka eraldi.]]>
      </Description>
      <ImageUrl>http://www.piletilevi.ee/imageGenerator/18ad67687ce2692a6cab7a00eb61b142/eventDetails</ImageUrl>
      <Performers>
        <Performer role="producer"><![CDATA[Ivar Põllu]]></Performer>
        <Performer role="actor"><![CDATA[Maarja Jakobson]]></Performer>
        <Performer role="actor"><![CDATA[Maarja Mitt]]></Performer>
        <Performer role="actor"><![CDATA[Helgur Rosenthal]]></Performer>
      </Performers>
    </EventContent>
    <StartTime type="ISO 8601">01-04-2017T17:00+03:00</StartTime>
    <DurationInMinutes>135</DurationInMinutes>
    <Venue id="15" country="EST" municipality_id="2" capacity="250">
      <Name><![CDATA[Tartu Uus Teater]]></Name>
      <Description lang="est"><![CDATA[Tartu Uus Teater on avatud platvorm uutele ideedele.]]></Description>
      <Description lang="eng"><![CDATA[Tartu Uus Teater is an open platform for new ideas.]]></Description>
      <Location lat="59.3953" lng="26.7443"/>
    </Venue>
    <PriceInfo>
      <Price min="10.00" max="12.00" />
    </PriceInfo>
  </Event>
</Events>

XML schema (XSD)

<?xml version="1.0" encoding="utf-8"?>

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Events">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Categories">
          <xs:complexType>
            <xs:sequence>
              <xs:element maxOccurs="unbounded" name="Category">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute name="id" type="xs:unsignedByte" use="required" />
                      <xs:attribute name="lang" type="xs:string" use="required" />
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="Municipalities">
          <xs:complexType>
            <xs:sequence>
              <xs:element maxOccurs="unbounded" name="Municipality">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute name="id" type="xs:unsignedInt" use="required" />
                      <xs:attribute name="country" type="xs:string" use="required" />
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element maxOccurs="unbounded" name="Event">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="EventContent">
                <xs:complexType>
                  <xs:all>
                    <xs:element name="Title" type="xs:string" minOccurs="1" maxOccurs="1"/>
                    <xs:element name="Categories">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element maxOccurs="unbounded" name="Category">
                            <xs:complexType>
                              <xs:attribute name="id" type="xs:unsignedByte" use="required" />
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                    <xs:element name="Description">
                      <xs:complexType>
                        <xs:simpleContent>
                          <xs:extension base="xs:string">
                            <xs:attribute name="lang" type="xs:string" use="required" />
                          </xs:extension>
                        </xs:simpleContent>
                      </xs:complexType>
                    </xs:element>
                    <xs:element name="ImageUrl" type="xs:string" />
                    <xs:element name="Performers">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element maxOccurs="unbounded" name="Performer">
                            <xs:complexType>
                              <xs:simpleContent>
                                <xs:extension base="xs:string">
                                  <xs:attribute name="role" type="xs:string" use="optional" />
                                </xs:extension>
                              </xs:simpleContent>
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:all>
                  <xs:attribute name="id" type="xs:unsignedInt" use="required" />
                </xs:complexType>
              </xs:element>
              <xs:element name="StartTime">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute name="type" type="xs:string" use="required" />
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:element name="DurationInMinutes" type="xs:unsignedInt" />
              <xs:element name="Venue">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="Name" type="xs:string" />
                    <xs:element maxOccurs="unbounded" name="Description">
                      <xs:complexType>
                        <xs:simpleContent>
                          <xs:extension base="xs:string">
                            <xs:attribute name="lang" type="xs:string" use="required" />
                          </xs:extension>
                        </xs:simpleContent>
                      </xs:complexType>
                    </xs:element>
                    <xs:element name="Location">
                      <xs:complexType>
                        <xs:attribute name="lat" type="xs:decimal" use="required" />
                        <xs:attribute name="lng" type="xs:decimal" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="id" type="xs:unsignedInt" use="required" />
                  <xs:attribute name="country" type="xs:string" use="required" />
                  <xs:attribute name="municipality_id" type="xs:unsignedInt" use="required" />
                  <xs:attribute name="capacity" type="xs:unsignedInt" />
                </xs:complexType>
              </xs:element>
              <xs:element name="PriceInfo">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="Price">
                      <xs:complexType>
                        <xs:attribute name="min" type="xs:decimal" use="required" />
                        <xs:attribute name="max" type="xs:decimal" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="id" type="xs:unsignedInt" use="required" />
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

XSLT 1 (html)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output method="html" indent="yes"/>

  <!-- template for calculating Julian day -->
  <!-- used for reference: http://stackoverflow.com/questions/5544762/finding-the-difference-between-2-dates-in-xslt -->
  <xsl:template name="calculateJulianDay">
    <xsl:param name="year"/>
    <xsl:param name="month"/>
    <xsl:param name="day"/>
    <xsl:variable name="a" select="floor((14 - $month) div 12)"/>
    <xsl:variable name="y" select="$year + 4800 - $a"/>
    <xsl:variable name="m" select="$month + 12 * $a - 3"/>

    <xsl:value-of select="$day + floor((153 * $m + 2) div 5) + $y * 365 + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045"/>
  </xsl:template>
  
  <!-- dummy base date for date comparison -->
  <xsl:variable name="dateTodayDummy" select="20170320"/>
  <xsl:variable name="todayDateJulian">
    <xsl:call-template name="calculateJulianDay" >
      <xsl:with-param name="year" select="substring($dateTodayDummy,1,4)"/>
      <xsl:with-param name="month" select="substring($dateTodayDummy,5,2)"/>
      <xsl:with-param name="day" select="substring($dateTodayDummy,7,2)"/>
    </xsl:call-template>
  </xsl:variable>

  <!-- template for calculating event start time -->
  <xsl:template name="calculateStartTime">
    <xsl:param name="timeString"/>
    <xsl:variable name="baseHours" select="substring($timeString,1,2)"/>
    <xsl:variable name="addHours" select="substring($timeString,7,2)"/>
    
    <xsl:value-of select="$baseHours + $addHours"/>
  </xsl:template>
  
  <xsl:template match="/">
    <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html&gt;</xsl:text>
    <html>
      <head>
        <title>Ticteter - Esileht</title>
      </head>
      <body>

        <hr/>
        <h2 style="text-align: center">Peagi toimumas!</h2>
        <hr/>
        
        <xsl:for-each select="Events/Event">
          <!-- finding comparison date -->
          <xsl:variable name="node" select="StartTime" />
          <xsl:variable name="dateOfEvent" select="concat(substring(string($node),7,4),substring(string($node),4,2),substring(string($node),1,2))" />

          <xsl:variable name="compareDateJulian">
            <xsl:call-template name="calculateJulianDay">
              <xsl:with-param name="year" select="substring($dateOfEvent,1,4)"/>
              <xsl:with-param name="month" select="substring($dateOfEvent,5,2)"/>
              <xsl:with-param name="day" select="substring($dateOfEvent,7,2)"/>
            </xsl:call-template>
          </xsl:variable>

          <!-- display item if less than 30 days to event -->
          <xsl:if test="$compareDateJulian - $todayDateJulian  &lt; 30">
            <!-- event's info -->
            <div style="float: left; width: 200px; margin: 20px">
              <!-- event photo -->
              <img alt="eventart" height="300" width="200">
                <xsl:attribute name="src">
                  <xsl:value-of select="EventContent/ImageUrl"/>
                </xsl:attribute>
              </img><br/>
              <!-- event title -->
              <span style="font-weight: bold">
                <xsl:value-of select="EventContent/Title"/>
              </span><br/>
              <!-- date -->
              <xsl:variable name="Date" select="concat(substring(string($node),1,2),'.',substring(string($node),4,2),'.',substring(string($node),7,4))" />
              <xsl:value-of select="$Date"/><br/>
              <!-- time -->
              <xsl:variable name="startTime">
                <xsl:call-template name="calculateStartTime">
                  <xsl:with-param name="timeString" select="substring($node,12,11)"/>                 
                </xsl:call-template>
              </xsl:variable>
              <xsl:value-of select="concat($startTime,':',substring(string($node),15,2))"/><br/>
              <!-- venue -->
              <xsl:value-of select="Venue/Name"/><br/>
              <!-- price range -->
              <xsl:text> </xsl:text><xsl:value-of select="PriceInfo/Price/@min"/>-<xsl:value-of select="PriceInfo/Price/@max"/>
            </div>
          </xsl:if>
        </xsl:for-each>
        <div style="clear: left"></div>

        <hr/>
        <h2 style="text-align: center">Kõik üritused</h2>
        <hr/>
        <xsl:for-each select="Events/Event">
          <xsl:variable name="node" select="StartTime" />
          <!-- event's info -->
          <div style="float: left; width: 200px; margin: 20px">
            <!-- event photo -->
            <img alt="eventart" height="300" width="200">
              <xsl:attribute name="src">
                <xsl:value-of select="EventContent/ImageUrl"/>
              </xsl:attribute>
            </img><br/>
            <!-- event title -->
            <span style="font-weight: bold">
              <xsl:value-of select="EventContent/Title"/>
            </span><br/>
            <!-- date -->
            <xsl:variable name="Date" select="concat(substring(string($node),1,2),'.',substring(string($node),4,2),'.',substring(string($node),7,4))" />
            <xsl:value-of select="$Date"/><br/>
            <!-- time -->
            <xsl:variable name="startTime">
              <xsl:call-template name="calculateStartTime">
                <xsl:with-param name="timeString" select="substring($node,12,11)"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:value-of select="concat($startTime,':',substring(string($node),15,2))"/><br/>
            <!-- venue -->
            <xsl:value-of select="Venue/Name"/><br/>
            <!-- price range -->
            <xsl:text> </xsl:text><xsl:value-of select="PriceInfo/Price/@min"/>-<xsl:value-of select="PriceInfo/Price/@max"/>
          </div>
        </xsl:for-each>
        <div style="clear: left"></div>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

XSLT 2 (html)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <!-- template for calculating event start time -->
  <xsl:template name="calculateStartTime">
    <xsl:param name="timeString"/>
    <xsl:variable name="baseHours" select="substring($timeString,1,2)"/>
    <xsl:variable name="addHours" select="substring($timeString,7,2)"/>
    <xsl:value-of select="$baseHours + $addHours"/>
  </xsl:template>

  <xsl:output method="html" indent="yes"/>

  <xsl:template match="/">
    <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html&gt;</xsl:text>
    <html>
      <head>
        <title>Ticteter - Sündmused asula järgi</title>
      </head>
      <body>
        <hr/>
        <h2 style="text-align: center">Sündmused asula järgi</h2>
        <hr/>

        <xsl:for-each select="Events/Municipalities/Municipality">
          <xsl:variable name="municipalityId" select="@id" />
          <xsl:variable name="municipalityName" select="." />
          <hr/>
          <h2 style="text-align: center">
            <xsl:value-of select="$municipalityName"/>
          </h2>

          <xsl:for-each select="/Events/Event">
            <xsl:if test="Venue/@municipality_id = $municipalityId">
              <xsl:variable name="node" select="StartTime" />
              <!-- event's info -->
              <div style="float: left; width: 200px; margin: 20px">
                <!-- event photo -->
                <img alt="eventart" height="300" width="200">
                  <xsl:attribute name="src">
                    <xsl:value-of select="EventContent/ImageUrl"/>
                  </xsl:attribute>
                </img>
                <br/>
                <!-- event title -->
                <span style="font-weight: bold">
                  <xsl:value-of select="EventContent/Title"/>
                </span>
                <!-- date -->
                <xsl:variable name="Date" select="concat(substring(string($node),1,2),'.',substring(string($node),4,2),'.',substring(string($node),7,4))" />
                <xsl:value-of select="$Date"/><br/>
                <!-- time -->
                <xsl:variable name="startTime">
                  <xsl:call-template name="calculateStartTime">
                    <xsl:with-param name="timeString" select="substring($node,12,11)"/>
                  </xsl:call-template>
                </xsl:variable>
                <xsl:value-of select="concat($startTime,':',substring(string($node),15,2))"/><br/>
                <!-- venue -->
                <xsl:value-of select="Venue/Name"/><br/>
                <!-- price range -->
                <xsl:text> </xsl:text><xsl:value-of select="PriceInfo/Price/@min"/>-<xsl:value-of select="PriceInfo/Price/@max"/>
              </div>
            </xsl:if>
          </xsl:for-each>

          <!-- Check if there are any events in the area -->
          <xsl:if test="count(/Events/Event/Venue[@municipality_id = $municipalityId]) = 0">
            Piirkonnas ei ole lähiajal ühtegi sündmust.
          </xsl:if>

          <div style="clear: left"></div>

          <hr/>
        </xsl:for-each>

      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

XSLT 3 (xml)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <Categories>
      <xsl:for-each select="Events/Categories/Category[@lang='est']">
        <xsl:variable name="catId" select="@id" />
        <xsl:variable name="catName" select="." />
        <Category>
          <xsl:attribute name="id">
            <xsl:value-of select="@id"/>
          </xsl:attribute>
          <name>
            <xsl:value-of select="."/>
          </name>
          <xsl:for-each select="/Events/Event">
            <xsl:if test="EventContent/Categories/Category/@id = $catId">
              <event>
                <xsl:copy-of select="EventContent/Title"/>
                <xsl:copy-of select="EventContent/Performers"/>
                <date>
                  <xsl:value-of select="substring(StartTime,1,10)"/>
                </date>
                <time>
                  <xsl:value-of select="substring(StartTime,12,5)"/>
                </time>
                <venue>
                  <xsl:value-of select="Venue/Name" />
                </venue>
                <minprice>
                  <xsl:value-of select="PriceInfo/Price/@min"/>
                </minprice>
                <maxprice>
                  <xsl:value-of select="PriceInfo/Price/@max"/>
                </maxprice>
                <xsl:if test="$catName='Sport'">
                  <discount>
                    <reduction unit="percent">50</reduction>
                    <clientGroup>MyFitness</clientGroup>
                    <clientGroup>Sparta</clientGroup>
                  </discount>
                </xsl:if>
              </event>
            </xsl:if>
          </xsl:for-each>
        </Category>
      </xsl:for-each>
    </Categories>
  </xsl:template>
</xsl:stylesheet>

Retsensioonid