Analizzare l’XML significa essenzialmente la navigazione attraverso un documento in formato XML per la restituzione dei dati pertinenti. Un numero crescente di servizi web restituiscono i dati in formato JSON, ma un gran numero restituiscono ancora i dati in formato XML, quindi è necessario padroneggiare l’analisi dell’XML, se davvero si vuole servire dell’intera gamma di API disponibili.
Utilizzando l’estensione SimpleXML di PHP, che è stato introdotto nel PHP 5.0, lavorare con l’XML è molto facile. In questo post si mostra come fare.
languages.xml
:<languages>
<lang name="C">
<appeared>1972</appeared>
<creator>Dennis Ritchie</creator>
</lang>
<lang name="PHP">
<appeared>1995</appeared>
<creator>Rasmus Lerdorf</creator>
</lang>
<lang name="Java">
<appeared>1995</appeared>
<creator>James Gosling</creator>
</lang>
</languages>
[/code]
Il primo passo è quello di caricare il codice XML utilizzando la funzione simplexml_load_file()
o simplexml_load_string()
. Come ci si potrebbe aspettare, la prima carica il file XML da un file e la successiva carica il codice XML da una stringa data.
$languages = simplexml_load_file("languages.xml");
?>
[/code]
SimpleXMLElement
. Nell’esempio precedente, l’oggetto viene memorizzato nella variabile $languages. È quindi possibile utilizzare var_dump()
o print_r()
per ottenere i dettagli dell’oggetto restituito, se volete.(
[lang] => Array
(
[0] => SimpleXMLElement Object
(
[@attributes] => Array
(
[name] => C
)
[appeared] => 1972
[creator] => Dennis Ritchie
)
[1] => SimpleXMLElement Object
(
[@attributes] => Array
(
[name] => PHP
)
[appeared] => 1995
[creator] => Rasmus Lerdorf
)
[2] => SimpleXMLElement Object
(
[@attributes] => Array
(
[name] => Java
)
[appeared] => 1995
[creator] => James Gosling
)
)
)
[/code]
languages
come radice che è avvolto tre elementi lang, motivo per cui il SimpleXMLElement
ha lang
come proprietà pubblica che sarebbe un array di tre SimpleXMLElements
. Ciascun elemento dell’array corrisponde ad un elemento lang
nel documento XML.
È possibile accedere alle proprietà dell’oggetto nel solito modo con l’operatore ->
. Ad esempio, $languages->lang[0]
] vi darà un oggetto SimpleXMLElement
che corrisponde al primo elemento lang
. Questo oggetto ha due proprietà pubbliche: appeared e creator.
$languages->lang[0]->appeared;
$languages->lang[0]->creator;
?>
[/code]
foreach
.foreach ($languages->lang as $lang) {
printf(
">%s apparso nel %d ed è stato creato da %s.",
$lang["name"],
$lang->appeared,
$lang->creator
);
}
?>
[/code]
lang
per recuperare il nome della lingua. È possibile accedere a qualsiasi attributo di un elemento rappresentato come un oggetto SimpleXMLElement
utilizzando la notazione di array come questo di sopra.languages.xml
per rispecchiare l’utilizzo degli spazi dei nomi<languages
xmlns:dc="http://purl.org/dc/elements/1.1/">
<lang name="C">
<appeared>1972</appeared>
<dc:creator>Dennis Ritchie</dc:creator>
</lang>
<lang name="PHP">
<appeared>1995</appeared>
<dc:creator>Rasmus Lerdorf</dc:creator>
</lang>
<lang name="Java">
<appeared>1995</appeared>
<dc:creator>James Gosling</dc:creator>
</lang>
</languages>
[/code]
creator
è posto sotto il namespace dc
che punta a http://purl.org/dc/elements/1.1/. Se si tenta di stampare il creatore di una linguaggio usando la tecnica precedente, non funzionerà. Per leggere gli elementi namespace come questo è necessario utilizzare uno dei seguenti approcci.
Il primo approccio è quello di utilizzare l’URI dello spazio dei nomi direttamente nel codice quando si accede a elementi namespace.
Nell’esempio riportato di seguito viene illustrato come:
$dc = $languages->lang[1]- >children("http://purl.org/dc/elements/1.1/");
echo $dc->creator;
?>
[/code]
children()
prende uno spazio dei nomi e restituisce i figli dell’elemento preceduto. Accetta due argomenti: il primo è lo spazio dei nomi XML e il secondo è un valore booleano opzionale che per impostazione predefinita è su false. Se si passa true, lo spazio dei nomi sarà trattato come un prefisso piuttosto come l’URI del namespace attuale.
Il secondo approccio è quello di leggere l’URI dello spazio dei nomi dal documento e utilizzarlo durante l’accesso agli elementi del namespace. Questo è in realtà il modo più pulito per accedere agli elementi, perché non c’è bisogno di codificare l’URI.
$namespaces = $languages->getNamespaces(true);
$dc = $languages->lang[1]->children($namespaces["dc"]);
echo $dc->creator;
?>
[/code]
getNamespaces()
restituisce un array con i prefissi dello spazio dei nomi con il loro URI associato. Accetta un parametro opzionale il cui valore predefinito è false. Se lo si imposta true allora il metodo restituirà gli spazi dei nomi utilizzati in nodi principali e secondari. In caso contrario, non trova spazi dei nomi utilizzati solo nel nodo genitore.
Ora è possibile scorrere l’elenco delle linguaggi in questo modo:
$languages = simplexml_load_file("languages.xml");
$ns = $languages->getNamespaces(true);
foreach($languages->lang as $lang) {
$dc = $lang->children($ns["dc"]);
printf(
">%s apparso nel %d ed è stato creato da %s.",
$lang["name"],
$lang->appeared,
$dc->creator
);
}
?>
[/code]
[/code]
- Video URL
- Thumbnail
- Title
$channel = "channelName";
$url = "http://gdata.youtube.com/feeds/api/users/".$channel."/uploads";
$xml = file_get_contents($url);
$feed = simplexml_load_string($xml);
$ns=$feed->getNameSpaces(true);
?>
[/code]
entity
) ciascuno dei quali memorizza i dettagli di un video dal canale. Ma se ci interessa solo un’immagine in miniatura, URL del video e il titolo. I tre elementi sono figli del gruppo (group
), che è un figlio dell’entrata (entry
):<media:group>
<media:player url="video url"/>
<media:thumbnail url="video url" height="height" width="width"/>
<media:title type="plain">Title </media:title>
</media:group>
</entry>
[/code]
entry
, e per ogni loop è possibile estrarre le informazioni pertinenti. Si noti che nel player
il thumbnail
e il title
sono tutti sotto lo spazio dei nomi dei media
. Quindi, abbiamo bisogno di procedere come nell’esempio precedente: ottenere gli spazi dei nomi del documento e utilizzare lo spazio dei nomi durante l’accesso agli elementi.foreach ($feed->entry as $entry) {
$group=$entry->children($ns["media"]);
$group=$group->group;
$thumbnail_attrs=$group->thumbnail[1]->attributes();
$image=$thumbnail_attrs["url"];
$player=$group->player->attributes();
$link=$player["url"];
$title=$group->title;
printf(‘<a href="%s"><img src="%s" alt="%s"></a>’,
$player, $image, $title);
}
?>
[/code]
Ancora nessun commento