-
Query DOM
Carico un file XML con DOM:
Codice PHP:
$dom->loadXML($xml);
Il file XML è:
Codice:
<? xml version="1.0" ?>
<campionato>
<squadra>
<nome>juventus</nome>
<punti>50</punti>
<giocatore>Buffon</giocatore>
<giocatore>Chiellini</giocatore>
<giocatore>Cannavaro</giocatore>
...
<giocatore>Giovinco</giocatore>
</squadra>
<squadra>
<nome>milan</nome>
<punti>40</punti>
<giocatore>Dida</giocatore>
<giocatore>Nesta</giocatore>
<giocatore>Zambrotta</giocatore>
...
<giocatore>Gattuso</giocatore>
</squadra>
</campionato>
Vorrei ottenere il nome di una qualunque squadra che ha X punti...come faccio?
-
Il modo più semplice è usare XPath, ma ti consiglio di abbandonare DOMDocument a favore di SimpleXML che è decisamente più flessibile e semplice da usare.
Codice PHP:
$xml = simplexml_load_string($xml);
$punti = 50;
/*
prende nome per ogni squadra che ha punti = $punti (50)
restituisce un array di SimpleXMLElements
*/
$nodi = $xml->xpath('/campionato/squadra[punti=\''.$punti.'\']/nome');
foreach($nodi as $nodo)
echo $nodo[0];
Ciao!
-
Mi servirebbe anche la scrittura, non solo la lettura. Comunque preferirei DOMDocument...cercavo un esempio.
-
Se proprio vuoi rimanere con DOMDocument c'è la classe DOMXPath che fa lo stesso; la sintassi di XPath è standard, quindi ti rimane solo da capire come sfruttarne i metodi.
Purtroppo la modifica è sempre un problema, perchè ogni volta è necessario riscrivere l'XML da capo.
Che io sappia lo devi trattare come una stringa, che alla fine scriverai sul file. Ma potrebbero esserci metodi migliori.
Ciao!
-
Ho bisogno di DOM puro, niente XPath o simili.
-
Beh? Scorri tutti i nodi squadra e per ognuno verifichi che punti sia uguale al valore che cerchi.
Metodi richiesti: getElementsByTagName(), item() - nel primo link c'è anche un esempio con un xml molto simile al tuo, devi solo adattarlo.
Ciao!
-
Ok sono riuscito. Grazie.
Ora vorrei creare una nuova squadra, sempre con DOM. Mi date qualche dritta?
-
Questo dovrebbe essere un esempio abbastanza completo:
Codice PHP:
<?php
$xml = new DOMDocument ();
$xml->load ("campionato.xml");
// accedi all'elemento principale del file
$root = $xml->documentElement;
// crea la nuova squadra
$squadra = $xml->createElement ("squadra");
// definisci il nome e il punteggio
$nome = $xml->createElement ("nome", "Inter");
$squadra->appendChild ($nome);
$punti = $xml->createElement ("punti", "ne ho più io sulla patente");
$squadra->appendChild ($punti);
// definisci i giocatori
for (...)
{
$giocatore = $dom->createElement ("giocatore", "...");
$squadra->appendChild ($giocatore);
}
// aggiungi la squadra al campionato (l'elemento principale)
$root->appendChild ($squadra);
// salva il file XML aggiornato
$bytes = $xml->save ("campionato_v2.0.xml");
echo "Scritti $bytes byte sul file";
?>
Stammi bene...
-
Grazie mille, chiarissimo.
E se volessi aggiungere il nodo allenatore a una squadra già esistente?
-
Devi prima creare l'emento e poi usare DOMDocument::appendChild
Codice PHP:
$xml = new DOMDocument();
$xml->load("campionato.xml");
$root = $xml->documentElement;
$allenatore = $xml->createElement("allenatore", "nome_allenatore");
$squadra = $root->getElementsByTagName("squadra")->item(0);
$squadra->appendChild($allenatore);
$xml->save("campionato.xml");
-
Dovrei esserci.
Se con getElementsByTagName volessi selezionare tutti i giocatori di una certa squadra come potrei fare?
-
Codice PHP:
$xml = new DOMDocument();
$xml->load("campionato.xml");
$root = $xml->documentElement;
$squadra = $root->getElementsByTagName("squadra")->item(n); // n sta per il numero della squadra, 0 equivale al primo elemento trovato
foreach($squadra->getElementsByTagName("giocatore") as $giocatore) {
echo $giocatore->nodeValue . "<br />";
}
-
Ho racchiuso tutti i giocatori di ogni squadra nel tag <rosa>.
Ora voglio aggiungere il giocatore Mario Rossi nella squadra Juventus.
Codice PHP:
$squadra=$dom->getElementsByTagName("squadra");
foreach ($squadra as $squadra)
if ($squadra->getElementsByTagName("nome")->item(0)->nodeValue=="juventus")
$juve=$squadra->getElementsByTagName("nome")->item(0);
$acquisto=$dom->createElement("giocatore","Mario Rossi");
$rosa=$juve->getElementsByTagName("rosa")->item(0);
$rosa->appendChild($acquisto);
Mi da l'errore:
Codice:
Fatal error: Call to a member function appendChild() on a non-object
segnalato sull'ultima riga.
-
Ehm... nel ciclo foreach non è bene usare la stessa variabile per indicare l'oggetto su cui fai le iterazioni (quello a sinistra) e il riferimento all'iteratore corrente (a destra). Prova così:
Codice PHP:
$squadra=$dom->getElementsByTagName("squadra");
foreach ($squadra as $s)
if ($s->getElementsByTagName("nome")->item(0)->nodeValue=="juventus")
$juve=$s->getElementsByTagName("nome")->item(0);
$acquisto=$dom->createElement("giocatore","Mario Rossi");
$rosa=$juve->getElementsByTagName("rosa")->item(0);
$rosa->appendChild($acquisto);
-
Stesso errore di prima...
-
Potresti dirci, magari, quale è la riga interessata dall'errore? Comunque mi sembra strano che anche correggendo l'errore continui a darlo...
-
C'è un altro errore: l'attributo nodeValue non è definito su un elemento (in questo caso "nome"), ma sul suo discendente di tipo testuale. In pratica, con quel ciclo non troverai mai la variabile $juve (però non mi torna il fatto che non ti dia errore alla riga prima) e quindi la variabile $rosa.
Correggi la condizione:
Codice PHP:
if ($s->getElementsByTagName("nome")->item(0)->nodeValue=="juventus")
in questo modo:
Codice PHP:
if ($s->getElementsByTagName("nome")->item(0)->firstChild->nodeValue=="juventus")
Stammi bene...