9 XSL-muunnokset XML-dokumenttien keskeinen rooli on välittää tietoa sovellusten välillä. Yksinkertaisimmillaan tämä tarkoittaa sitä että tieto tuotetaan suoraan tietyn sovelluksen tekstiformaattiin. Lähestymistavan huono puoli on tekstiformaateista sopimisen vaiva ja pahimmassa tapauksessa sitoutuminen "köyhään" tietorakenteeseen. Yleisemmin parempi ratkaisu on tuottaa tietoa kohdesovellukseen muunnosten avulla. Tällöin tietoa kuvataan sovellusten välillä ohjelmallisesti, mikä helpottaa (XML-)sovellusten yhdistämistä. Yksinkertaisimmillaan muunnos on "tyylipohja" joka esittää tietyn tietosisällön esim. XHTML-sivuna. 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 150
9.1 Konseptiesimerkki A Tiedon ohjelmallinen kuvaaminen sanastosta toiseen on tyypillinen XML-sovellusten yhdistelyyn liittyvä tehtävä Case (huom. sis. monikanavajulkaisun ja käärimisen): - asiakashallintaohjelma A tuottaa tekstimuotoisia raportteja joita halutaan katsella/tulostaa/siirtää toisiin järjestelmiin raportti XSLTprosessori XHTML - sen sijaan että A ohjelmoitaisiin tuottamaan raporttinsa esim. XHTMLformaatissa, ohjelmoidaan tuloste omassa XML-formaatissa raportti - kirjoitetaan muunnos (tiedosto a2h.xsl) T: raportti XHTML a2h.xsl -...näin raportista voidaan helposti tuottaa muitakin esitystapoja, (raportin tietomallia ei tarvitse valita XHTML:n rajoitusten mukaan), jos XHTMLversio halutaan vaihtaa, muokataan vain muunnosta, kokonaan uusi kohdesovellus? ei edellytä A:n muokkaamista, vain uudentyyppisen muunnoksen kirjoittamista, jne. 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 151
9.2 Extensible Stylesheet Language: Transformations XML-perheen suositus XSLT (1.0) määrittelee ns. XSLT-prosessorin tai muuntimen toiminnallisuuden Muunnos on tietokoneohjelma joka kuvaa lähdedokumentin jäsennyspuun toiseen muotoon kohdedokumentin (tai tulosdokumentin) jäsennyspuuna - muunnos voi hyödyntää kaikkea XML-dokumentista löytyvää informaatiota (loogisen rakenteen osalta), mukaan lukien kommentit ja prosessointiohjeet 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 152
9.3 Esimerkki: yksinkertainen muunnos <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output method="html" indent="yes" encoding="iso-8859-1" doctype-public="-//w3c//dtd HTML 4.0 Transitional//EN" /> <xsl:template match="/music"> <html> <head> <title>esimerkki</title> <style type="text/css"> body { background: yellow;} </style> </head> <body> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="album"> <h2> <xsl:value-of select="@artist"/> </h2> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet> 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 153
9.4 Tekniikkaa XSLT tarjoaa kielen muunnosten kuvaamiseen se ei vielä yksin riitä Suositus XPath (XML Path Language (XPath) 1.0) tarjoaa kielen jäsennyspuiden osiin viittaamiseksi - "osoitin- ja ohjelmointikieli" (vrt. CSS2-valitsimet) Kohdesovellus voi olla mikä tahansa XML-tekstiformaatti - nimiavaruuksia tarvitaan erottamaan XSL kohteesta - lähdedokumentti (puu) on mv. XML-dokumentti - tulosdokumentti (puu) on mv. XML/HTML/tekstidokumentti (tai tekstientiteetti) XSLT:tä voidaan luonnehtia mallipohjaiseksi tai funktionaaliseksi ohjelmointikieleksi 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 154
9.5 Muunnoksen yleisrakenne Kärjistäen, tyypillinen XSL-muunnos sisältää seuraavat osat: output-osa kertoo tulospuun sarjallistuksen (ja esim. kohdedokumentin tyypin) Säännöt (template) määrittelevät muunnoksen loogisen sisällön (tiedon kuvaus lähdepuusta tulospuuksi) Parametrit tarjoavat keinon ohjata muunnoksia ulkoapäin, lähdedokumenttien ohella (esim. kytkiminä XSLT-prosessorille) Muunnokseen voidaan myös sisällyttää (include ja import) osia toisista muunnostiedostoista (modulaariset muunnokset) Suurin osa opiskelusta on sääntöjen ja näihin liittyvien "lauserakenteiden" ja komentojen opiskelua (...ja kohdesovellusten opiskelua...) 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 155
9.6 Sääntöjen anatomia Säännöt kirjoitetaan mallipohjien (template) avulla Sääntö aktivoituu lähdepuun aktiivisen kontekstin perusteella, säännön hahmon (pattern) ohjaamana Aktivoitunut sääntö tuottaa tulospuun ko. kohtaan sisältönsä, komentojen ohjaamana Sääntöjen (rekursiivinen) ketjutus ja oletussäännöt 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 156
9.7 XSLT-jäsennyspuun osat Muunnos näkee lähdedokumentin esiintymäosan solmuista koostuvana puuna - juurisolmu - elementtisolmut, attribuuttisolmut, prosessointiohjesolmut, tekstisolmut, - kommenttisolmut, nimiavaruussolmut Jokaista loogista elementtiä kohti löytyy rakenteensa XPath-kielestä sekä komentoja ko. tyyppisen tiedon käsittelyyn ja generoimiseen Solmun (suhteellinen) sijainti puussa osoitetaan ns. akselin avulla (vrt. CSS) - ancestor, ancestor-or-self, attribute, child, descendant, descendant-or-self, following, following-sibling, namespace, parent, preceding, precedingsibling, self 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 157
9.8 Hahmojen kielioppi (XPath & lokaatiopolku) Lokaatioaskelten kolmiosainen rakenne (akseli::solmutesti[predikaatti]): child::kirja/child::luku[position()=5]/child::kappale[position()=2] Käytössä on lyhennemerkintöjä. Esimerkkejä: para matches any para element * matches any element chapter appendix matches any chapter element and any appendix element olist/item matches any item element with an olist parent appendix//para matches any para element with an appendix ancestor element / matches the root node text() matches any text node processing-instruction() matches any processing instruction node() matches any node other than an attribute node and the id("w11") para[1] root node matches the element with unique ID W11 matches any para element that is the first para child 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 158
element of its parent *[position()=1 and self::para] matches any para element that is the first child element of its parent para[last()=1] matches any para element that is the only para child element of its parent items/item[position()>1] matches any item element that has a items parent and that is not the first item child of its parent item[position() mod 2 = 1] would be true for any item element that is an odd-numbered item child of its parent. div[@class="appendix"]//p matches any p element with a div ancestor element that has a class attribute with value appendix @class matches any class attribute (not any element that has a class attribute) @* matches any attribute 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 159
Vastaavasti esimerkkejä täydellisten lausekkeiden avulla child::para selects the para element children of the context node child::* selects all element children of the context node child::text() selects all text node children of the context node child::node() selects all the children of the context node, whatever their node type attribute::name selects the name attribute of the context node attribute::* selects all the attributes of the context node descendant::para selects the para element descendants of the context node ancestor::div selects all div ancestors of the context node ancestor-or-self::div selects the div ancestors of the context node and, if the context node is a div element, the context node as well descendant-or-self::para selects the para element descendants of the context node and, if the context node is a para element, the context node as well 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 160
self::para selects the context node if it is a para element, and otherwise selects nothing child::chapter/descendant::para selects the para element descendants of the chapter element children of the context node child::*/child::para selects all para grandchildren of the context node / selects the document root (which is always the parent of the document element) /descendant::para selects all the para elements in the same document as the context node /descendant::olist/child::item selects all the item elements that have an olist parent and that are in the same document as the context node child::para[position()=1] selects the first para child of the context node 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 161
child::para[position()=last()] selects the last para child of the context node child::para[position()=last()-1] selects the last but one para child of the context node child::para[position()>1] selects all the para children of the context node other than the first para child of the context node following-sibling::chapter[position()=1] selects the next chapter sibling of the context node preceding-sibling::chapter[position()=1] selects the previous chapter sibling of the context node /descendant::figure[position()=42] selects the forty-second figure element in the document 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 162
/child::doc/child::chapter[position()=5]/child::section[position()=2] selects the second section of the fifth chapter of the doc document element child::para[attribute::type="warning"] selects all para children of the context node that have a type attribute with value warning child::para[attribute::type='warning'][position()=5] selects the fifth para child of the context node that has a type attribute with value warning child::para[position()=5][attribute::type="warning"] selects the fifth para child of the context node if that child has a type attribute with value warning child::chapter[child::title='introduction'] selects the chapter children of the context node that have one or more title children with stringvalue equal to Introduction 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 163
child::chapter[child::title] selects the chapter children of the context node that have one or more title children child::*[self::chapter or self::appendix] selects the chapter and appendix children of the context node child::*[self::chapter or self::appendix][position()=last()] selects the last chapter or appendix child of the context node 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 164
9.9 Laajempi esimerkki: music HTML(4) Tuotetaan musictiedoista Web-sivu Esimerkissä esille nousevia tyypillisiä pulmia/tehtäviä: - ohjelmoinnin pulmat idref id music.xml copy.xml bandinfo.xml XSLT-prosessori m2h.xsl - mallintamisen pulmat, erityisesti: miten tieto jaetaan eri dokumenttien kesken (normalisointi, avaimet, asiasisältö vs. tyyli, yms.) - teknisen kirjoittamisen pulmat out.html -...tyypitys, kieliversiointi, lokaalit, tiedon ylläpito, virhetilanteiden hallinta, suorituskyky, yms. 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 165
9.10 Takaisin perusteisiin: oletussäännöt Prosessoinnin jatkaminen (kaikilla moodeilla) <xsl:template match="* /"> <xsl:apply-templates/> </xsl:template> <xsl:template match="* /" mode="m"> <xsl:apply-templates mode="m"/> </xsl:template> Tekstin tuottaminen <xsl:template match="text() @*"> <xsl:value-of select="."/> </xsl:template> Prosessointiohjeiden ja kommenttien sivuuttaminen <xsl:template match="processing-instruction() comment()"/> Myös oletussäännöt voi määritellä uudelleen 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 166
9.11 Output XSL-muunnos käsittelee lähinnä tiedon loogista kuvaamista lähdepuusta kohdepuuksi, tiedon sarjallistus on kuitenkin useissa sovelluksissa keskeistä <!-- Category: top-level-element --> <xsl:output method = "xml" "html" "text" qname-but-not-ncname version = nmtoken encoding = string omit-xml-declaration = "yes" "no" standalone = "yes" "no" doctype-public = string doctype-system = string cdata-section-elements = qnames indent = "yes" "no" media-type = string /> Huomioita: XML vs. HTML vs. teksti 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 167
9.12 XSLT-komennot (1/2) Kohdesolmujen tuottaminen (ns. literaalien ohella): - xsl:element, xsl:attribute (ja xsl:attribute-set), xsl:text, xsl:processinginstruction, xsl:comment - vrt. erot literaalien kanssa (attribuutit ja kommentit!) Lähdepuun kopiointi - xsl:copy, xsl:copy-of Tekstin tuottaminen - xsl:value-of Numerointi - xsl:number 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 168
9.13 XSLT-komennot (2/2) Toistolauseet - xsl:for-each - vrt. sääntöjen suorittaminen Ehtolauseet - xsl:if, xsl:choose, xsl:when, xsl:otherwise Järjestäminen - xsl:sort Muuttujien käsittely - xsl:variable, xsl:param Muuta: Viestit ja laajennukset 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 169
9.14 Lausekkeet ja funktiot (XPath ja XSLT) XPath-kieli sisältää ohjelmoinnissa tyypillisesti tarvittavat rakenteet - tietotyypit (node-set, boolean, number, string) - muuttujat ($v), liukuluvuilla laskeminen (+, -, *, div, mod) ehtolausekkeet (or, and, =,!=, <=, <, >=, >) ja funktioiden kutsuminen (concat($v,$x)) - huomaa < ja '/""-merkkien käyttö merkkijonoissa (XML-tekstiä!) Kuten yleensä ohjelmoinnissa, lisäksi tarvitaan aliohjelmakirjastoja (joista osa olisi periaatteessa kuitenkin mahdollista kirjoittaa esim. sääntöinä) XSL-muunnosten yhteydessä käytössä ovat - Node Set Functions, String Functions, Boolean Functions, Number Functions, XSLT:n omat funktiot (erit. node-set document(object, nodeset?) ja node-set key(string, object)) Mahdolliset laajennukset 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 170
9.15 Muuttujien käsittelystä Funktionaalisen ohjelmoinnin hengessä muuttujat (muotoa $nimi) instantioidaan kerran ilman "päällekirjoittamisen" mahdollisuutta (tämä ei yleensä ole ongelma koska sääntöjä kutsutaan funktionaalisesti) Muuttujia tarvitaan esim. sääntöjen paloitteluun, merkkijonojen käsittelyyn (funktioiden käyttö) ja viittausrakenteiden kokoamiseen Keskeinen käyttö on myös parametrien välittäminen muunnoksille (päätason komentona) <xsl:param name="year" select="."/> Attribuuttien arvoina muuttujien evaluointi onnistuu myös sijoitusoperaation avulla ({ }-notaatio ja ns. attribute value template) <xsl:variable name="image-dir">/images</xsl:variable> <xsl:template match="photograph"> <img src="{$image-dir}/{href}" width="{size/@width}"/> </xsl:template> 7307015 RAKENTEISET DOKUMENTIT (kevät 2005) - ON 171