Potřebujete pomoci s XSLT?
Nabízím školení, konzultace, vývoj XSLT kódu na zakázku. Nevájte a kontaktujte mne.

Podpořte provoz stránek
Platba probíhá pomocí služby PayPal a je možné platit kartou nebo převodem z vašeho PayPal účtu.

13.3 Matematické funkce

13.3.1. math:min
13.3.2. math:max
13.3.3. math:highest
13.3.4. math:lowest
13.3.5. Výpočetní funkce
Jmenný prostor

http://exslt.org/math

Typický prefix

math

13.3.1 math:min

Výběr minima.

číslo math:min(seznam uzlů)

13.3.2 math:max

Výběr maxima.

číslo math:max(seznam uzlů)

13.3.3 math:highest

Výběr uzlu/uzlů s největší hodnotou.

seznam uzlů math:highest(seznam uzlů)

13.3.4 math:lowest

Výběr uzlu/uzlů s nejnižší hodnotou.

seznam uzlů math:lowest(seznam uzlů)

13.3.5 Výpočetní funkce

Většina XSLT procesorů podporuje i výpočtové matematické funkce – goniometrické funkce, logaritmy a exponenciální funkce. Můžeme je využít ve stylech, které provádějí složitější výpočty.

Představme si, že máme nějakou statistiku v podobě dokumentu XML.

Příklad 13.7. Statistická data jako dokument XML – prohlizece.xml

<?xml version="1.0" encoding="utf-8"?>
<prohlizece>
  <klient podil="69.5">IE6</klient>
  <klient podil="6.5">IE5</klient>
  <klient podil="2.4">Opera 7</klient>
  <klient podil="16.6">Mozilla</klient>
  <klient podil="0.2">NN3</klient>
  <klient podil="0.2">NN4</klient>
  <klient podil="1.4">NN7</klient>
</prohlizece>

Nyní ji chceme prezentovat v přehledné podobě jako koláčový graf. I pro tento úkol zdánlivě nesouvisející s XML a XSLT, nemusíme používat jiné technologie. Vektorové obrázky lze reprezentovat formátu SVG, který je založen na XML. Není tedy příliš složité převést data v XML do SVG právě pomocí transformace XSLT. Protože při vytváření koláčového grafu potřebujeme spočítat souřadnice bodů ležící na kruhu, využijeme s výhodou matematické funkce EXSLT.

Obrázek 13.1. Koláčový graf v SVG vygenerovaný pomocí XSLT

Koláčový graf v SVG vygenerovaný pomocí XSLT

Příklad 13.8. Generování XHTML+SVG – kolacovy-graf.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:svg="http://www.w3.org/2000/svg"
                xmlns:math="http://exslt.org/math"
                xmlns:b="urn:x-kosek:barvy"
                extension-element-prefixes="math"
                exclude-result-prefixes="b"
                version="1.0">

<!--  
<xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

Protože je IE prasátko a neumí korektně zpracovat XHTML, musíme mu
SVG vložit do něčeho, co je spíše HTML. Fuj! :-(

V Opeře 8 to funguje dobře, stačí nechat method="xml"
-->
<xsl:output method="html"/>

<!-- Konstanta π -->  
<xsl:variable name="pi" select="3.1415926535"/>

<!-- Kódy barev, které se postupně použijí pro jednotlivé výseče grafu -->  
<b:barvy>
  <barva>#FF7D00</barva>
  <barva>#B35800</barva>
  <barva>#FFDFBF</barva>
  <barva>#FFBE80</barva>
  <barva>#006EB0</barva>
  <barva>#004D7B</barva>
  <barva>#BFE7FF</barva>
  <barva>#80CFFF</barva>
  <barva>#320199</barva>
  <barva>#23016B</barva>
  <barva>#D4C0FF</barva>
  <barva>#A980FF</barva>
  <barva>#FFCB00</barva>
  <barva>#B38E00</barva>
  <barva>#FFF2BF</barva>
  <barva>#FFE580</barva>
</b:barvy>

<!-- Celkový počet definovaných barev -->  
<xsl:variable name="pocetBarev" select="count(document('')//b:barvy/barva)"/>

<!-- Hlavní šablona -->  
<xsl:template match="prohlizece">
  <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <title>Statistika prohlížečů</title>
      <!-- Kód vyžadovaný Adobe SVG pluginem pro IE -->
      <object id="AdobeSVG" classid="clsid:78156a80-c6a1-4bbf-8e6a-3cd390eeb4e2"></object>
      <xsl:processing-instruction name="import">namespace="svg" implementation="#AdobeSVG"</xsl:processing-instruction>
    </head>
    <body>
      <h1>Statistika prohlížečů</h1>
      <table border="0">
        <tr>
          <td>
            <!-- Začátek SVG obrázku -->
            <svg:svg viewBox="0 0 2.1 2.1" width="10cm" height="10cm">
              <svg:g transform="translate(1.05,1.05) scale(1,-1)">
                <xsl:variable name="celkem" select="sum(klient/@podil)"/>
                <xsl:variable name="pomerUhlu" select="2 * $pi div $celkem"/>
                <!-- Pro každý prohlížeč se vygeneruje jedna výseč v grafu -->
                <xsl:for-each select="klient">
                  <xsl:variable name="x1" select="format-number(math:cos(sum(preceding-sibling::klient/@podil) * $pomerUhlu), '0.####')"/>
                  <xsl:variable name="y1" select="format-number(math:sin(sum(preceding-sibling::klient/@podil) * $pomerUhlu), '0.####')"/>
                  <xsl:variable name="x2" select="format-number(math:cos((sum(preceding-sibling::klient/@podil) + @podil) * $pomerUhlu), '0.#####')"/>
                  <xsl:variable name="y2" select="format-number(math:sin((sum(preceding-sibling::klient/@podil) + @podil) * $pomerUhlu), '0.#####')"/>
                  <xsl:variable name="uhel" select="@podil * $pomerUhlu"/>
                  <xsl:variable name="large-arc">
                    <xsl:choose>
                      <xsl:when test="$uhel >= $pi">1</xsl:when>
                      <xsl:otherwise>0</xsl:otherwise>
                    </xsl:choose>
                  </xsl:variable>
                  <xsl:variable name="pos" select="position()"/>
                  <xsl:variable name="fill" select="document('')//b:barvy/barva[($pos mod $pocetBarev) + 1]"/>
                  <svg:path d="M 0,0 L {$x1},{$y1} M {$x1},{$y1} A1,1 0 {$large-arc} 1 {$x2},{$y2} L 0,0" style="stroke:black; stroke-width: 0.005; fill:{$fill}"/>
                </xsl:for-each>
              </svg:g>
            </svg:svg>
          </td>
          <td>
            <!-- Vygenerováné legendy ke grafu -->
            <table cellpadding="4" cellspacing="4">
              <xsl:for-each select="klient">
                <xsl:variable name="pos" select="position()"/>
                <xsl:variable name="fill" select="document('')//b:barvy/barva[($pos mod $pocetBarev) + 1]"/>
                <tr>
                  <td bgcolor="{$fill}" width="20px" height="20px">&#160;</td>
                  <td><xsl:value-of select="."/> (<xsl:value-of select="@podil"/> %)</td>
                </tr>
              </xsl:for-each>
            </table>
          </td>
        </tr>
      </table>
    </body>
  </html>    
</xsl:template>

</xsl:stylesheet>

© Jiří Kosek 2014

Tento dokument je určen výhradně pro osobní potřebu seznámení s jazykem XSLT. Jakékoliv jiné použití, včetně dalšího šíření, pořizování kopií, použití při školeních a výuce apod. je výslovně zakázáno a bude považováno za porušení autorských práv.


Copyright © 2000-2014 Jiří Kosek