IPRO - PC Magazine Romania, 2002
Comunitatea experţilor şi a cititorilor PC Magazine
- Internet PRO
De
la XML la HTML
Mihai Târnovan
Oricine lucrează în domeniu TI&C a auzit măcar vorbindu-se, dacă nu chiar
a lucrat cu XML. Toată lumea vorbeşte despre această nouă "tehnologie",
serverele de aplicaţii "suportă XML", serviciile web suportă XML,
chiar şi noua infrastructură .NET a gigantului din Redmond e bazată pe XML.
Ba chiar şi baze de date bazate pe XML îşi fac apariţia încet dar sigur.
A ignora subiectul este cu siguranţă o mare greşeală, poate la fel de mare
precum ignorarea internetului şi a avantajelor evidente pe care le poate aduce
pentru o afacere acum câţiva ani, când a început să se dezvolte web-ul. În acest
articol voi încearca să evit bombardarea cititorului cu acronime (la o recitire
observ că nu am reuşit), atât de des folosite când se vorbeşte despre XML şi
prezentarea unui exemplu simplu implicând transformarea unui fişier XML în HTML
pentru a fi afişat într-un browser.
XML nu a fost gândit pentru a înlocui HTML-ul, dar poate ajuta la depăşirea
limitărilor pe care acesta din urmă le-a impus asupra dezvoltării web-ului în
ultimii anii. Cea mai importantă dintre acestea este lipsa informaţiei semantice
sau, altfel spus, HTML-ul descrie cum să fie prezentată informaţia fară să spună
nimic altceva despre informaţia în sine.
<html>
<body>
<h1>O pagină oarecare</h1>
<h2>Pagină scrisă de Mihai</h2>
</body>
</html><pagină>
<autor>Mihai</autor>
<conţinut>
<titlu>O pagină oarecare</titlu>
</conţinut>
</pagină>
Codul HTML nu conţine în sine nici o informaţie despre autorul paginii, ci
doar o propoziţie oarecare ("Pagină scrisă de Mihai") şi modul în
care această propoziţie să fie afişată pe ecran. Pentru calculator e greu să
afle cine este autorul acestei pagini. Tagurile meta încearcă să amelioreze
puţin situaţia, oferind un mecanism prin care pagina HTML se poate autodescrie,
dar au evidente limitări.
În schimb, din fragmentul XML e uşor de dedus cine a scris articolul şi pentru
un calculator, dar şi pentru utilizatorul sistemului de calcul. Tagul autor
conţine un string care desemnează numele autorului paginii. Pentru a "ştii"
acest lucru calculatorul nu trebuie să înţeleagă limba română, ca în fragmentul
HTML.
XML
este acronimul pentru eXtensible Markup Language. Este deci un limbaj de markup,
cum este şi HTML-ul. Dar spre deosebire de HTML, care a fost conceput pentru
a descrie cum să fie reprezentată informaţia, XML a fost gândit de la început
pentru a descrie informaţie. XML foloseşte două mecanisme pentru a descrie informaţia:
DTD (Document Type Definition) sau mai noul XML Schema, dar acestea nu fac subiectul
acestui articol. XML-ul în sine nu face deci nimic. El a fost conceput pentru
a structura, stoca şi facilita schimbul informaţiei.
Tagurile XML nu sunt predefinite ca la HTML, unde tagurile şi semnificaţia
lor este fixată (<body>,<p>,<h1> etc). Utilizatorul (cu sens
generic) trebuie să definească tagurile singur. În fragmentul XML de mai sus
autorul a "inventat" tagurile <pagină>,<autor>,<conţinut>
etc. El îşi va putea defini singur structura documentului şi tagurile folosite.
Tocmai din acest motiv un browser nu poate afişa un fişier XML.
Pentru a afişa informaţia conţinută în fişiere XML este necesară transformarea
acestuia în HTML. Avem nevoie de XSL (eXtensible Stylesheet Language), un limbaj
special creat pentru a facilita transformarea fişierelor XML în alte fişiere
XML sau - mai interesant pentru noi - în fişiere HTML.
XSL este compus de fapt din 3 tehnologii: XSLT, XPath şi XSL:FO. Lăsând detaliile
la o parte, XSL poate fi privit ca un limbaj de transformare a XML-ului în (X)HTML,
un limbaj care facilitează manipularea informaţiei XML prin filtrare şi sortare,
poate defini părţi dintr-un document XML, poate formata datele din fişierele
XML pe baza valorilor acestora (de exemplu să afişeze valorile mai mici de 100
cu roşu în loc de verde). Acest limbaj poate produce output pentru diverse medii
cum ar fi ecran, hârtie sau chiar voce, dar ne vom limita la aspectul cel mai
folosit, producere de XHTML.
Cea mai importantă tehnologie din XSL este XSTL adică XSL Transformations.
Acesta este folosit pentru a produce dintr-un arbore XML sursă un arbore XML
rezultat. Arborele rezultat poate fi un fişier în format XHTML, iar pe parcursul
transformării, elemente din arborele sursă pot fi ignorate sau altele noi pot
fi adăugate sau sortate după diverse criterii. În timpul transformării se pot
lua decizii cu privire la ce elemente se transformă şi cum. Să vedem un exemplu:
<?xml
version="1.0" encoding="ISO-8859-2"?>
<?xml-stylesheet type="text/xsl" href= "catalog.xsl"?>
<catalog>
<cd>
<titlu>Calling All Destroyers</titlu>
<artist>Metallica</artist>
<tara>SUA</tara>
<an>1984</an>
<pret>17.90</pret>
</cd>
<cd>
<titlu>Ride the Lightning</titlu>
<artist>Metallica</artist>
<tara>SUA</tara>
<an>1989</an>
<pret>19.90</pret>
</cd>
<cd>
<titlu>And Justice for All</titlu>
<artist>Metallica</artist>
<tara>SUA</tara>
<an>1990</an>
<pret>29.90</pret>
</cd>
<cd>
<titlu>Oceanborn</titlu>
<artist>Nightwish</artist>
<tara>Norvegia</tara>
<an>1999</an>
<pret>12.90</pret>
</cd>
<cd>
<titlu>Razorblade Romance</titlu>
<artist>HIM</artist>
<tara>SUA</tara>
<an>2000</an>
<pret>13.90</pret>
</cd>
<cd>
<titlu>Hybrid Theory</titlu>
<artist>Linkin Park</artist>
<tara>SUA</tara>
<an>2001</an>
<pret>18.90</pret>
</cd>
<cd>
<titlu>The First Years of Piracy</titlu>
<artist>Running Wild</artist>
<tara>SUA</tara>
<an>2002</an>
<pret>19.90</pret>
</cd>
<cd>
<titlu>Vovin</titlu>
<artist>Therion</artist>
<tara>Suedia</tara>
<an>1998</an>
<pret>29.90</pret>
</cd>
</catalog>
Acesta va fi fişierul XML pe care vrem să îl afişăm într-un browser. Să vedem
fişierul XSL care va efectua transformarea:
<?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>
<TABLE border="0" cellspacing="1" cellpadding="3">
<TR bgcolor="silver">
<TH>Artist</TH>
<TH>Titlu</TH>
<TH>Ţara</TH>
<TH>An</TH>
<TH>Preţ</TH>
</TR>
<xsl:apply-templates select = "catalog/ cd">
<xsl:sort select="artist"/>
<xsl:sort select="titlu"/>
</xsl:apply-templates>
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="cd">
<TR>
<xsl:apply-templates select="artist"/>
<xsl:apply-templates select="titlu"/>
<xsl:apply-templates select="tara"/>
<xsl:apply-templates select="an"/>
<xsl:apply-templates select="pret"/>
</TR>
</xsl:template>
<xsl:template match="titlu">
<TD>
<xsl:apply-templates/>
</TD>
</xsl:template>
<xsl:template match="artist">
<TD>
<B>
<xsl:apply-templates/>
</B>
</TD>
</xsl:template>
<xsl:template match="tara">
<TD>
<xsl:apply-templates/>
</TD>
</xsl:template>
<xsl:template match="an">
<TD>
<xsl:apply-templates/>
</TD>
</xsl:template>
<xsl:template match="pret">
<TD STYLE="font-style:italic">
<xsl:value-of select="."/> EU
</TD>
</xsl:template>
</xsl:stylesheet>
Puţine browsere au suport de XSL la ora actuală. Suportul XSL din Internet
Explorer 5 si 5.5 nu este bazat pe standardul oficial W3C, ci pe o specificaţie
mai veche aflată încă în stadiul de propunere. Internet Explorer 6, în schimb,
suportă complet ultimul set de specificaţii XSL dat de W3C. Parserele XML livrate
de Microsoft au ajuns la versiunea 3 la lansarea Windows XP şi Internet Explorer
6. De atunci Microsoft a mai lansat versiunea 4. Exemplele din acest articol
pot fi urmărite pe Internet Explorer 6 şi, probabil, pe Netscape 6. Neajunsurile
browserelor mai vechi le-am putea evita dacă am folosi scripting sau pe partea
de server sau pe partea de client, utilizând obiectele COM oferite de MSXML.
Dacă salvaţi fragmentele de cod pe disc în acelaşi director sub numele catalog.xml
şi catalog.xsl, puteţi deschide fişierul catalog.xml cu Internet Explorer 6.
Veţi vedea că fişierul XML a fost transformat şi afişat pe ecran după cum ne
aşteptam. Transformarea se face automat de către browser. Aceasta metodă este
adecvată mai degrabă unor scopuri "didactice". În practică, de cele
mai multe ori transformarea se face pe partea de server, clientul primind un
simplu stream HTML.
Să disecăm puţin fişierul XSL, dar nu înainte de a observa că în fişierul XML
există o referinţă la fişierul XSL. Această referinţă va fi folosită de către
browser pentru efectuarea transformării.
<?xml-stylesheet
type="text/xsl" href="catalog.xsl"?>
Conform recomandării W3C, elementul rădacină care declară un fişier XSL este
<xsl:stylesheet> sau <xsl:transform> (ele sunt sinonime). Conţinutul
elementului rădăcină se compune dintr-un set de reguli şablon (template rules)
declarate cu elemente <xsl:template>. Aceste reguli şablon sunt de fapt
partea cea mai importantă a unui fişier XSL. Un şablon poate conţine şi text
care va apărea nemodificat în documentul rezultat, în fişierul nostru de exemplu:
<HTML>
<BODY>
<TABLE border="1" cellspacing="0" cellpadding="2">
...
Observăm că au fost definite şabloane pentru elementele cd, titlu, artist,
ţară, an, preţ. Fragmentul următor:
<xsl:apply-templates
select="catalog/cd">
<xsl:sort select="artist"/>
<xsl:sort select="titlu"/>
</xsl:apply-templates>
aplică şabloanele definite mai jos pe toate elementele cd ale elementului catalog,
selectându-le sortate după artist şi titlu.
Şablonul pentru elementul cd:
<xsl:template
match="cd">
<TR>
<xsl:apply-templates select="artist" />
<xsl:apply-templates select="titlu" />
<xsl:apply-templates select="tara" />
<xsl:apply-templates select="an" />
<xsl:apply-templates select="pret" />
</TR>
</xsl:template>
aplică pe fiecare dintre subelementele acestuia şabloanele aferente. Elementul
<xsl:apply-templates select=expresie mode=mod> selectează întâi un set
de noduri folosind criteriul specificat de atributul select. Dacă acesta nu
este specificat, vor fi selectaţi toţi descendenţii nodului curent. Pentru fiecare
nod astfel selectat, procesorul XSLT va căuta un şablon corespunzător. Şabloanele
sunt testate comparând nodul cu expresia XPath specificată în atributul match
al şabloanelor. Atributul mode este folosit pentru procesarea multiplă a elementelor.
Un <xsl:apply-templates> care are setat atributul mode se va aplica doar
pe şabloane care au setat atributul mode la aceeaşi valoare.
Astfel, elementul <xsl:apply-templates select="pret"/> din
fragmentul de mai sus va avea ca efect aplicarea şablonului
<xsl:template
match="pret">
<TD STYLE="font-style:italic">
<xsl:value-of select="."/> EU
</TD>
</xsl:template>
atributul select al elementului apply-templates şi atributul match al elementului
xsl:template indicând acelaşi nod.
Vorbeam la începutul articolului despre posibilităţile XSLT-ului de a modifica
modul în care sunt afişate informaţiile, de a adăuga elemente noi în funcţie
de datele conţinute în fişierul XML. Să modificăm deci exemplul nostru pentru
a afişa cu roşu elemente an mai mici de 2000 şi cu verde pe cele mai mari. În
acest scop, modificăm şablonul aplicat elementului an în felul următor:
<xsl:template
match="an">
<TD>
<xsl:attribute name="style">
<xsl:choose>
<xsl:when test=" (. <= 2000)">
color:red;
</xsl:when>
<xsl:otherwise>
color:green;
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates />
</TD>
</xsl:template>
Să începem cu elementul <xsl:attribute>. Acesta îl vom folosi pentru
a seta atributul style al elementului <TD> în funcţie de valoarea conţinută
de elementul an. Numele atributului ce va fi adăugat elementului <TD>
e dat de atributul name, iar valoarea de conţinutul elementului <xsl:attribute>.
Am ajuns la elementul <xsl:choose>. Acesta ne pune la dispoziţie un mecanism
de testare condiţională şi se foloseşte împreună cu elementele <xsl:otherwise>
şi <xsl:when>. Subnodurile <xsl:when> ale elementului <xsl:choose>
sunt testate în ordine de sus în jos până când atributul test al unuia dintre
aceste elemente descrie cu acurateţe condiţiile prezente în informaţia sursă
sau se ajunge la un element <xsl:otherwise>. După ce s-a ales un element
prin <xsl:otherwise> sau <xsl:when>, se iese automat din blocul
<xsl:choose>. În cazul nostru, testul este ca valoarea numerică a elementulului
an să fie mai mică decât 2000:
<xsl:when
test=" (. <= 2000)">
caz în care valoarea elementului <xsl:attribute> este color:red. Dacă
valoarea este mai mare, se va ajunge la elementul <xsl:otherwise> şi conţinutul
elementului <xsl:attribute> va fi color:green. Condiţia în sine este
(. <= 2000 )
adică valoarea elementului curent ("." selectează elementul curent)
să fie mai mică (< - less than) de valoarea 2000. Se foloseşte <,
caracterul "<" având alte semnificaţii.
Să vedem ce mai ştie XSLT-ul să facă. Putem folosi face de exemplu totalul preţurilor
cd-urilor din catalog. Pentru aceasta adaugăm înainte de sfârşitul tag-ului
de tabelă:
....
<TR>
<TD colspan="4"> <B> <I> Total</I> </B>
</TD>
<TD><B><I>
<xsl:value-of select="format-number(sum(catalog/cd/pret),'###,###.00')"/>EU
</I></B></TD>
</TR>
</TABLE>
...
Elementul <xsl:value-of> inserează un string reprezentând valoarea primului
element (în ordinea din document) specificat de atributul select. Noi vom specifica
la atributul select o expresie care va calcula suma noastra. Funcţia format-number
converteşte valori numerice în stringuri. Primeşte ca parametrii valoarea de
intrare şi două stringuri folosite pentru formatarea numărului, dintre care
ultimul e opţional şi nu e folosit în exemplu.
În exemplu dat, valoarea de intrare este rezultatul funcţiei sum aplicată pe
elementele pret ale elementelor cd din elementul catalog. Funcţia sum este o
funcţie XPath care returnează suma tuturor nodurilor dintr-un set de noduri
primit ca parametru. Alte funcţii numerice XPath sunt round, ceiling, floor
şi number, primele trei se folosesc la rotunjire, ultima face conversia argumentului
într-un număr.

Am văzut deci drumul pe care îl urmează un fişier XML până la afişarea acestuia
în browser. Iată codul XHTML rezultat din transformare:
Nici un webdesigner nu mai creează astăzi scriind codul HTML manual. Argumentul
unui cod mai "curat" a pierdut de mult în faţa unui argument mult
mai importat: productivitatea. La capitolul unelte de dezvoltare, HTML-ul stă
foarte bine.
Din păcate uneltele care să ajute webdesignerul sau programatorul să lucreze
cu XML-XSL sunt deocamdată puţine. Şi de ce să nu recunoaştem, la prima vedere
se pare că a folosi combinaţia XML-XSL în loc de HTML pare a fi o mare pierdere
de vreme. Trebuie însă avute în vedere alte aspecte care fac o astfel de combinaţie
foarte folositoare: cu tehnologia XSL se poate transforma un fişier XML pentru
o varietate de medii sau formate (PDF, WML, SVG etc.), se separă prezentarea
de conţinut.
O aplicaţie care poate uşura mult munca depusă de programator este XML-Spy
produs de Altova. Pe situl www.xmlspy.com se poate descărca o versiune demo.
XML-Spy conţine chiar şi o aplicaţie vizuală de construit fişiere XSL, care
se bazează pe fişiere XML Schema. XML-Spy poate fi foarte util şi celor care
vor să înveţe să folosească noile tehnologii.
Există soluţii web bazate pe cuplul XML-XSL, una dintre cele mai cunoscute
este probabil Cocoon de la Apache Group (xml.apache.org). Acesta este practic
un server de web care foloseşte streamuri XML statice sau dinamice pe care le
transformă în XHTML, PDF, SVG, WML, RTF în timpul servirii clientului, folosind
streamuri XSL statice sau dinamice. De fapt, Cocoon nu este un server de web
propriu-zis, ci un servlet scris pentru container-ul de servleturi Tomcat, dezvoltat
tot de Apache Group. Un astfel de mediu foloseşte tehnologia XSL la adevăratul
ei potenţial.E
<HTML>
<BODY>
<TABLE border="0" cellspacing="1" cellpadding="3">
<TR bgcolor="silver">
<TH>Artist</TH>
<TH>Titlu</TH>
<TH>Ţara</TH>
<TH>An</TH>
<TH>Preţ</TH>
</TR>
<TR>
<TD>
<B>HIM</B>
</TD>
<TD>Razorblade Romance</TD>
<TD>SUA</TD>
<TD style= "color: red;">2000</TD>
<TD STYLE="font-style:italic">13.90 EU</TD>
</TR>
<TR>
<TD>
<B>Linkin Park</B>
</TD>
<TD>Hybrid Theory </TD>
<TD>SUA</TD>
<TD style="color: green;" >2001</TD>
<TD STYLE="font-style:italic">18.90 EU</TD>
</TR>
<TR>
<TD>
<B>Metallica</B>
</TD>
<TD>And Justice for All</TD>
<TD>SUA</TD>
<TD style="color: red;">1990</TD>
<TD STYLE="font-style:italic">29.90 EU</TD>
</TR>
<TR>
<TD>
<B>Metallica</B>
</TD>
<TD>Calling All Destroyers</TD>
<TD>SUA</TD>
<TD style="color: red;">1984 </TD>
<TD STYLE="font-style:italic">17.90 EU</TD>
</TR>
<TR>
<TD>
<B>Metallica</B>
</TD>
<TD>Ride the Lightning</TD>
<TD>SUA</TD>
<TD style="color:red;">1989</TD>
<TD STYLE="font-style:italic">19.90 EU</TD>
</TR>
<TR>
<TD>
<B>Nightwish</B>
</TD>
<TD>Oceanborn</TD>
<TD>Norvegia</TD>
<TD style="color: red;">1999</TD>
<TD STYLE="font-style:italic">12.90 EU</TD>
</TR>
<TR>
<TD>
<B>Running Wild</B>
</TD>
<TD>The First Years of Piracy</TD>
<TD>SUA</TD>
<TD style="color: green;">2002</TD>
<TD STYLE="font-style:italic">19.90 EU</TD>
</TR>
<TR>
<TD>
<B>Therion</B>
</TD>
<TD>Vovin</TD>
<TD>Suedia</TD>
<TD style="color: red;">1998</TD>
<TD STYLE="font-style:italic">29.90 EU</TD>
</TR>
<TR>
<TD colspan="4">
<B>
<I>Total</I>
</B>
</TD>
<TD>
<B>
<I>163.20EU
</I>
</B>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
|