domenica, gennaio 02, 2011

Basi di Dati: PHP ed XML

PHP ed XML

XML ci permette di definire una base di dati semi-strutturata (non sono costretto a scriverne lo schema)
E' possibile definire degli schema xml con dtd (più vecchio, meno usato ora) o xsd (xsd è basato su xml a sua volta)
In xml è obbligatoria nella prima riga l'intestazione xml (nell' es. le parti in grassetto sono obbligatorie <?xml version="1.0" encoding="UTF-8">) che è l'unico "tag" che non viene chiuso.
Esisono diversi modi di leggere un xml con php (in generale con ogni linguaggio di programmazione che supporta xml)

XPath

E' un linguaggio basato su xml che permette di indirizzare nodi ed attributi di xml.
Ha una sintassi simile a quella del filesystem. Il carattere / all'inizio di un xpath rappresenta la root e ogni nome seguito da / indica un element a sua volta. Es:
<Root><Element1><Element11 attr="ciao"></Element11><Element12 attr="Piero"></Element12></Element1></Root>
Posso indicare Element11 con /Element1/Element11
Ammette * come carattere jolly. | indica un or logico (es.: /Element1/Element11 | /Element1/Element12
. indica la posizione attuale nell'albero. .. il padre della posizione attuale
// indica qualsiasi percorso tra 2 nodi (es. Root//Element12 indica tutti gli element12 che si trovano a qualsiasi livello sotto Root)
Posso indicare dei predicati (come se fosse una where sql)
book[title="titolo"] (presenza di un sotto-elemento di nome title con valore "titolo")
book[@title="titolo"] (presenza di un attributo di nome title con valore "titolo")
book/chapter[name = "pluto" | name = "pippo"]
book/chapter[position() = 1]
book [count(chapter) < 10)
book[title contains(text(), "miotesto")]

W3C Document Object Model (DOM)

DOM è uno standard W3C e definisce un metodo comune a tutti i linguaggi di programmazione che lo implementano di leggere un xml.
Si parte dalla root e si naviga andando ai sottonodi. Il testo contenuto in un nodo è considerato un nodo a sua volta (???).
La differenza di visione tra SAX e DOM è sintetizzata nella slide seguente:

Inizializzo DOM: $dom = new DomDocument();

Lettura xml con DOM

Carico l'xml che voglio leggere (oppure salto se voglio creare un xml da zero): $dom->load('filename');
Individuazione del nodo radice: $root = $dom->documentElement;
Scorro i figli finché non incontro quello che mi interessa $root->childNodes; e a loro volta i loro figli.
In alternativa posso prendere direttamente un array di nodi con XPath:
$xp = new DomXPath($dom);
$nodes = $xp->query('espressioneXPath' [, $nodoDaCuiValutare]); Dove nodoDaCuiValutare è un nodo (di default dovrebbe essere la root) da cui valutare eventuali percorsi relativi contenuti nell'XPath passato.
I nodi possono essere di due tipi: XML_ELEMENT_NODE (nodo vero e proprio) o XML_TEXT_NODE (testo in un nodo). Si vede dalla proprietà: $node->nodeType;
Il nome del nodo è: $node->nodeName; Il valore di un nodo testuale è: $node->nodeValue;
Gli attributi del nodo (se presenti) sono nella proprietà: $node->nodeAttributeNode; Rende una array chiave-valore (nome=chiave)

Scrittura xml con DOM

Creare un nodo: $root = $dom->CreateElement('nome');
Impostarlo come radice: $dom->appendChild($root); o come figlio di un altro nodo: $node->appendChild($otherNode);
Creazione attributi: $node->setAttribute('nome', 'valore');
Inserimento di un nodo testuale: $node->appendChild($dom->createTextNode('testo contenuto'));
Salvataggio: $mioXml = $dom->saveXML();

Simple Api Xml (SAX)

Scorre un documento xml e solleva un eventi all'apertura di un tag e alla chiusura di un tag
Si crea il parser $xml = xml_parser_create('UTF-8');
Si inizializza la gestione degli eventi:
xml_set_element_handler($xml, 'funzioneDaRichiamareAllAperturaDiUnTag', 'funzioneDaRichiamareAllaChiusuraDiUnTag')
xml_set_character_data_handler($xml, 'funzioneDaRichiamareConIlContenutoDiUnTag')
L'implementazione delle funzioni (nomi cambiati per abbreviare):
function opentag($xml, $tag, $attr) {}
function closetag($xml, $tag) {}
function content($xml, $data) {}

Nessun commento: