03 de febrer 2008

XML i XSLT

Primer de tot, sapigueu que vaig actualitzar l'altre post "About Python" afegint-hi fragments de codi i tal i qual i ara que ja he fet l'SPAM:
A aquestes alçades , crec que ja tothom ha sentit anomenar les sigles: XML, però crec també que molts pocs saben què volen dir, per a què serveixen (més enllà d'una ampliació de l'html) i encara més, com es fa servir.
XML: eXtensible Markup Language, és un llenguatge no pas de programació si no més aviat per assignar valors a determinats objectes. Certament, no és un llenguatge limitat al sector web sinó que es pot extendre a tota la inform+atica essent per exemple un bon mètode per a guardar dades al disc, per exemple en un videojoc podríem tenir una cosa similar a aquesta:

<equip_personatges>
<personatge>
<nom> Cloud</nom>
<nivell> 3</nivell>
<punts_exp> 3455</punts_exp>
</personatge>
<personatge>
<nom>Barret</nom>
<nivell> 2 </nivell>
<punts_exp> 2695</punts_exp>
</personatge>
<personatge>
<nom>Tifa</nom>
<nivell> 2 </nivell>
<punts_exp> 2074</punts_exp>
</personatge>
</equip_personatges>

Aquest podria ser ben bé l'arxiu que guardem a la memory card del Final Fantasy VII [que no l'és ni molt menys, és tant sols un exemple :P]
Bé, com veieu és molt simple, tenim unes marques que les rodegem entre els caràcters "<" i ">" i hi podem posar els noms que volem, no tenim la restricció que tenim amb html que només certes marques són acceptades (&ltb>, &lttable>, ...). Això, sí, hem de generar un text ben format, no podem tancar una marca fins que no haguem tancat les marques internes. També ens podem imaginar el codi xml com un arbre, a on l'arrel seria "&ltequip_personatges>" i una fulla seria el "&ltnivell>". Per tant, tot i que no és obligat, és molt bo posar el codi segmentat amb tabuladors doncs amb un ràpid cop d'ull es veu tota la informació clarament i sense confusió (cosa que també va bé a l'hora de corretgir els errors amb el nostre codi).
Com a html també podem tenir marques amb atributs:


<?xml version="1.0" encoding="ISO-8859-15"?>
<equip_personatges>
<personatge sexe = "home">
<nom>Cloud</nom>
<nivell> 3</nivell>
<punts_exp> 3455</punts_exp>
</personatge>
<personatge sexe = "home">
<nom>Barret</nom>
<nivell> 2</nivell>
<punts_exp> 2695</punts_exp>
</personatge>
<personatge sexe = "dona">
<nom>Tifa</nom>
<nivell> 2</nivell>
<punts_exp> 2074</punts_exp>
</personatge>
</equip_personatges>


Determina si una informació la posem com una marca o com un atribut, dependrà de nosaltres. Però un cop haguem decidit que pels personatges el sexe s'indica com un atribut, tots els personatges, si se li indica el sexe, se li indicarà com a atribut, és obvi, però bé, hi ha gent que comença a fer paranoies rares.
A XML, tenim les entitats, que sincerament és una collonada però jo us ho poso per si algú hi troba una utilitat més útil que la de tenir el valor d'una variable global:
<!ENTITY nom_del_joc "Final fantasy VII">
Que es referenciaria amb algo així:


<review>
<joc>&nom_del_joc;</joc>
<descripcio>bla, bla, bla ...</descripcio>
</review>


Els comentaris que volguem posar en el nostre codi, tenen la mateixa sintaxis que amb html, i.e:
<!-- Això és un comentari que serà ignorat a l'hora de processar el codi xml -->
Molt bé, tot això està de maravella, però com accedim a les dades? doncs fent servir el que en diuen XPath (que no és altre cosa que aplicar la lògica i imaginar-se l'arbre com si fós un directori a Unix). Així que, seguint l'exemple del FF VII, si vull saber els noms dels personatges que tinc, accediria així:

equip_personatges/personatge/nom

Vegem que comencem de l'arrel i anem baixant,Però com que l'XML és super fashion, podem dir directament:

nom

I obtindrem el mateix resultat. Clar que fent servir aquest mètode pot ser liós, o si imaginem que a sota tenim els objectes com ara:

<?xml version="1.0" encoding="ISO-8859-15"?>
<equip_personatges>
<personatges>
<personatge sexe = "home">
<nom>Cloud</nom>
<nivell> 3</nivell>
<punts_exp> 3455</punts_exp>
</personatge>
<personatge sexe = "home">
<nom>Barret</nom>
<nivell> 2</nivell>
<punts_exp> 2695</punts_exp>
</personatge>
<personatge sexe = "dona">
<nom>Tifa</nom>
<nivell> 2</nivell>
<punts_exp> 2074</punts_exp>
</personatge>
</personatges>
<equipament>
<objecte>
<nom>Poció</nom>
<descripcio> +150 HP</descripcio>
</objecte>
</equipament>
</equip_personatges>

Doncs clar, no tant sols obtindríem els noms dels personatges si no que també els noms dels objectes, Així que les diferents maneres per obtenir els noms dels personatges serien: (una linia és una manera)

equip_personatges/personatges/personatge/nom
personatges//nom
personatges/*/nom
equip_personatges/equipament/../personatges/personatge/nom

I anar fent, molt semblant al sistema de directoris Unix. I què passa amb els atributs? Doncs ben senzill: Si volem saber el sexe dels nostres personatges:
equip_personatges/personatges/personatge@sexe
Només les dones:

equip_personatges/personatges/personatge[@sexe="dona"]

Els personatges amb un nivell igual o superior a 3:

equip_personatges/personatges/personatge[nivell>=3]

I ara estic notant una cosa, i és que no tinc manera de saber de quin sexe és en Cloud o quin nivell té en Barret, amb lo qual responc: desconec la manera de com es fa o és que simplement hauria de canviar el codi xml de la següent manera:

<?xml version="1.0" encoding="ISO-8859-15"?>
<equip_personatges>
<personatges>
<Cloud sexe = "home">
<nivell> 3</nivell>
<punts_exp> 3455</punts_exp>
</Cloud>
<Barret sexe = "home">
<nivell> 2</nivell>
<punts_exp> 2695</punts_exp>
</Barret>
<Tifa sexe = "dona">
<nivell> 2</nivell>
<punts_exp> 2074</punts_exp>
</Tifa>
</personatges>
<equipament>
<objecte>
<nom>Poció</nom>
<descripcio>+150 HP</descripcio>
</objecte>
</equipament>

</equip_personatges>

I ara sí que podem saber el sexe del Cloud:

equip_personatges/personatges/Cloud@sexe

I el nivell del Barret:

equip_personatges/personatges/Barret/nivell

I el nivell del Barret i la Tifa:

equip_personatges/personatges/Barret|Tifa/nivell

Així que, quin mètode és millor? doncs depèn, l'XML tindrà una plantilla a on s'indicarà què s'ha de fer en cada cas[encara que l'xml es faci servir com a mètode per guardar la partida, nosaltres hauríem de programar com llegir les dades]. Així que depenent de quina sigui la informació que ens interessa, voldrem fer una opció o una altre. És a dir, si tots els personatges es tracten igual (es carreguen igual a memòria: el propi programa ja s'organitzarà després per a tractar les dades) triaríem la primera opció, en canvi, si no tenim cap altre programa al darrere (fem servir l'XML per penjar-ho directament a la web) i ens interessa que cada personatge es mostri diferent doncs hauríem d'escollir aquest últim xml.
I vinga, fem un pas endavant i pleguem: XSLT (eXtensible Stylesheet Language Transformations):
I ara si vull tenir una web a on em surti tota la informació de la meva partida, hauria de crear la plantilla que traduís el meu codi xml a codi html, primer tindrem el nostre codi xml:

<?xml version="1.0" encoding="ISO-8859-15"?>
<?xml-stylesheet type="text/xsl" href="partida.xsl"?>
<equip_personatges>
<personatges>
<personatge sexe = "home">
<nom>Cloud</nom>
<nivell> 3</nivell>
<punts_exp> 3455</punts_exp>
</personatge>
<personatge sexe = "home">
<nom>Barret</nom>
<nivellɮ</nivell>
<punts_exp> 2695</punts_exp>
</personatge>
<personatge sexe = "dona">
<nom>Tifa</nom>
<nivell> 2</nivell>
<punts_exp> 2074</punts_exp>
</personatge>
</personatges>
<equipament>
<objecte>
<nom>Poció</nom>
<descripcio>+150 HP</descripcio>
</objecte>
</equipament>
</equip_personatges>

I tot seguit la nostra plantilla anomenada partida.xsl:

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

<xsl:template match="personatge">
<p>Nom: <b><xsl:value-of select="./nom"/></b></p>
<p>nivell: <xsl:value-of select="./nivell"/></p>
<p>punts experiencia: <xsl:value-of select="./exp"/></p>
</xsl:template>

<xsl:template match="equipament">
<p>Nom: <b><xsl:value-of select="./*/nom"/></b></p>
<p>descripció: <xsl:value-of select="./*/descripcio"/></b></p>
</xsl:template>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

I això clar, hauria de funcionar i tal i qual, ja ho provaré penjant-ho al servidor i tal i qual. Tot això està basat amb el tutorial aquest.
I pels qui volgueu posar en una web els caràcters < i > sense cap mena d'error, ho haureu d'escriure seguint aquesta conversió.

3 comentaris:

Spiegel ha dit...

molt bon post! un 10!! : D

Neioo ha dit...

jejeje, no esperàveu pas menys, oi?

Neioo ha dit...

un altre enllaç a on trobar un tutorial de xslt:
http://geneura.ugr.es/~jmerelo/XSLT/
No sé quina moto de Saxon ens vol vendre però lo interessant no és pas el Saxon, si no com dóna exemples útils de XSLT.