XSLT

Az XSLT az egyik XSL nyelv. Az XSL jelentése: EXtensible Stylesheet Language. A CSS a HTML megjelenítésére szolgáló stílus nyelv. A HTML jól definiált megjelenítéssel rendelkezik: a CSS szerepe, hogy meghatározza a font, szín, méret, stb. attributumokat.

AZ XML azonban más. Egy adott TAG-et, pl. <TABLE> nem egyértelmű, hogyan kell megjeleníteni. Az XSL azt szabályoszza, hogyan kell megjeleníteni egy XML állományt.

Az XSLT jelentése: XSL Transformations.

Az XSLT egy XML állományt alakít át egy másik XML vagy más típusú állománnyá. Legtöbbször (X)HTML állománnyá alakít. Ugyanakkor az XSLT elhagyhat, vagy hozzáadhat új TAG-eket vagy attribútumokat is az átírás során.

Az átírás során egy XML forrás-fa kerül átalakításra egy XML eredmény-fá-ba.

Az XSLT az XPath-t használja az XML dokumentumon belüli navigálásra. Az alapelv a következő: az XSLT az XPath segítségével mintákat definiál a forrás-fában. Amikor egy minta illesztése sikerül, akkor az illeszkedő mintát átírjuk az eredmény-fába.

Az XSLT természetesen XML állomány. Így van gyökér eleme, ami kötelezően <xsl:stylesheet> vagy <xsl:transform>. Az xsl:stylesheet és xsl:transform teljesen ekvivalens. Ahhoz, hogy használhassuk az XSLT elemeket, attributumokat, az xsl névteren deklarálnunk kell a dokumentum elején:


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

Vegyük elő a jó öreg üzenetes példát (note1.xml):


<?xml version="1.0" encoding="ISO-8859-2"?>
<note id="1">
  <date>
    <year>2002</year>
    <month>12</month>
    <day>11</day>
  </date>
  <priority>urgent</priority>
  <to>Pista</to>
  <to>Peti</to>
  <from>Jani</from>
  <question>
    <body>Menjünk bringázni a hétvégén</body>
  </question>
</note>

És alkalmazzuk rá az alábbi minimális XSLT tranzformációt (tr1.xml):


<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
</xsl:stylesheet>

Például az alábbi parancssori módon:


$ xsltproc tr1.xml note1.xml

Az eredmény az alábbi:


gsd@dvd:~/work/uni/lecture/doku/pelda> xsltproc tr1.xml note1.xml
<?xml version="1.0"?>


    2002
    12
    11

  urgent
  Pista
  Peti
  Jani

    Menjünk bringázni a hétvégén



El lehet érni, hogy egy XML dokumentumot mindig egy adott XSLT dolgozzon fel. Ez elsősorban akkor hasznos, ha pl. egy HTML böngésző dolgozza fel. Ehhez be kell helyezni az alábbi sort: <?xml-stylesheet type="text/xsl" href="tr1.xml"?>


<?xml version="1.0" encoding="ISO-8859-2"?>
<?xml-stylesheet type="text/xsl" href="tr1.xml"?>
<note id="1">
  <date>
    <year>2002</year>
    <month>12</month>
    <day>11</day>
  </date>  
  <priority>urgent</priority>
  <to>Pista</to>
  <to>Peti</to>
  <from>Jani</from>
  <question>
    <body>Menjünk bringázni a hétvégén</body>
  </question>  
</note>

Próbáljunk azonosítani egy mintát, pl: <note> ... </note> Ennek az elemnek a teljes tartamát cseréljük ki a template-ben meghatározott mintára. A forrás-fa-beli minta definiálását a xsl:template elem definiálja. Az value-of pedig az eredmény-fa generált értékét a forrás-fa-beli <to> ... </to> elem értéke jelenti:


<?xml version="1.0" encoding="ISO-8859-2"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="note">
  <emphasis role="bold">
    <xsl:value-of select="to"/>
  </emphasis>
</xsl:template>
</xsl:stylesheet>

Az eredmény:


<?xml version="1.0"?>
<emphasis role="bold">Pista</emphasis>

A match határozza meg az illesztendő mintát. Az egyik gyakori eset a /, ami a teljes dokumentumot jelenti az XPath-ban.


<?xml version="1.0" encoding="ISO-8859-2"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <emphasis role="bold">
    Ez egy output.
  </emphasis>
</xsl:template>
</xsl:stylesheet>

Most a teljes dokumentumot cseréltük ki a bold elemek közötti értékre.


<?xml version="1.0"?>
<emphasis role="bold">
  Ez egy output.
</emphasis>

A következő példában szeretnénk nem egy konstans szöveget kiírni, hanem a forrás XML egy értékét. Ehhez a value-of elemet használjuk.


<?xml version="1.0" encoding="ISO-8859-2"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <emphasis role="bold">
    <xsl:value-of select="note/to"/> 
  </emphasis>
</xsl:template>
</xsl:stylesheet>

Az eredmény:


<?xml version="1.0"?>
<emphasis role="bold">Pista</emphasis>

Csakhogy egyetlen címzett jelent csak meg!

Ciklust kell szervezni. A ciklushoz a for-each elemet használjuk fel. Figyeljük meg, hogy a value-of select értékében már a for-each-hez relatív értéket adjuk meg.


<?xml version="1.0" encoding="ISO-8859-2"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xsl:for-each select="note/to">
    <emphasis role="bold">
      <xsl:value-of select="." />
    </emphasis>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Az eredmény most heylesen:


<?xml version="1.0"?>
<emphasis role="bold">Pista</emphasis><emphasis role="bold">Peti</emphasis>

A ciklusban szereplő mintákat tovább szűrhetjük az alábbi módon:


?xml version="1.0" encoding="ISO-8859-2"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xsl:for-each select="note/to[.='Peti']">
    <emphasis role="bold">
      <xsl:value-of select="." />
    </emphasis>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Az alábbi szűrő műveletek állnak rendelkezésünkre:

Az eredmény:

<?xml version="1.0"?>
<emphasis role="bold">Peti</emphasis>

Tudunk rendezni is:


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xsl:for-each select="note/to">
  <xsl:sort select="family"/>
    <emphasis role="bold">
      <xsl:value-of select="family" />
    </emphasis>
    <emphasis>
      <xsl:value-of select="first" />
    </emphasis>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Eredmény:


<?xml version="1.0"?>
<emphasis role="bold">Kiss</emphasis><emphasis>Peti</emphasis><emphasis role="bold">Nagy</emphasis><emphasis>Pista</emphasis>

Elágazás


<?xml version="1.0" encoding="ISO-8859-2"?>
<?xml-stylesheet type="text/xsl" href="tr1.xml"?>
<note id="1">
  <date>
    <year>2002</year>
    <month>12</month>
    <day>11</day>
  </date>  
  <priority>urgent</priority>
  <to>
    <first>Pista</first>
    <family>Nagy</family>
    <salary>250000</salary>
  </to>
  <to>
    <first>Peti</first>
    <family>Kiss</family>
    <salary>200000</salary>
  </to>  
    <to>
    <first>Pali</first>
    <family>Szegény</family>
    <salary>50000</salary>
  </to>  
  <from>Jani</from>
  <question>
    <body>Menjünk bringázni a hétvégén</body>
  </question>  
</note>

Ki akarjuk választani a 200000 feletti fizetésűeket.


<?xml version="1.0" encoding="ISO-8859-2"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xsl:for-each select="note/to">
    <xsl:sort select="family"/>
    <xsl:if test="salary &gt; 200000">
      <emphasis role="bold">
        <xsl:value-of select="family" />
      </emphasis>
      <emphasis>
        <xsl:value-of select="first" />
      </emphasis>
    </xsl:if>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Eredmény:


<?xml version="1.0"?>
<emphasis role="bold">Nagy</emphasis><emphasis>Pista</emphasis>

Használhatunk többszörös elágazásos szerkezetet is:


<?xml version="1.0" encoding="ISO-8859-2"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xsl:for-each select="note/to">
    <xsl:sort select="family"/>
    <xsl:choose>
      <xsl:when test="salary &gt; 200000">
        <emphasis role="bold">
          <xsl:value-of select="family" /> 
        </emphasis>  
        <emphasis>  
          <xsl:value-of select="first" /> 
        </emphasis>
      </xsl:when>  
      <xsl:when test="salary &gt; 150000">
        <emphasis>
          <xsl:value-of select="family" /> 
        </emphasis>  
        <emphasis>  
          <xsl:value-of select="first" /> 
        </emphasis>
      </xsl:when>  
      <xsl:otherwise>
        <emphasis>
          egyéb
        </emphasis>
      </xsl:otherwise>  
    </xsl:choose>
  </xsl:for-each>  
</xsl:template>
</xsl:stylesheet>

AZ eredmény:


<?xml version="1.0"?>
<emphasis>Kiss</emphasis><emphasis>Peti</emphasis>
<emphasis role="bold">Nagy</emphasis><emphasis>Pista</emphasis>
<emphasis>egyéb</emphasis>

Az egyik legfontosabb technika az XSLT-ben az apply-templates. Az apply-templates a kurrens elemre alkalmaz egy template-et, ill. annak gyerekeire. Amennyiben select attributumot adunk az apply-templates elemhez, akkor csak a megfelelő gyerekelemeket fogja tovább feldolgozni.


<?xml version="1.0" encoding="ISO-8859-2"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<body>
<h2>cimzettek</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

<xsl:template match="note/to">
<p>
<xsl:apply-templates select="family"/>
<xsl:apply-templates select="first"/>
</p>
</xsl:template>

<xsl:template match="family">
<emphasis>
<xsl:value-of select="."/>
</emphasis>
</xsl:template>

</xsl:stylesheet>

Az eredmény:


<html><body>
<h2>cimzettek</h2>

    2002
    12
    11

  urgent
  <p><emphasis>Nagy</emphasis>Pista</p>
  <p><emphasis>Kiss</emphasis>Peti</p>
  <p><emphasis>Szegény</emphasis>Pali</p>
  Jani

    Menjünk bringázni a hétvégén

</body></html>