da Array a XML e viceversa con PHP

 
Da array PHP a XML

Può essere utile, a volte, avere a disposizione delle funzioni che permettono di trasformare degli array in elementi XML, per esempio perché c'è necessità di fornire dei feed, o è necessario realizzare degli elementi particolari per comunicazioni verso altri dispositivi con chiamate REST (per esempio vogliamo creare delle API interrogabili e che possono fornire risposte in diversi linguaggi, come JSON, XMl, PHP serialized, ....), o con applicativi flash/flex/...

Reinventare ogni volta la ruota diventa scomodo e le problematiche che si hanno a gesitre il tutto tramite chiamate a SimpleXMLElement può non essere comodissimo, per questo ho realizzato questa classe che permette di trasformare (in maniera ricorsiva) degli array PHP in XML e viceversa, con la "particolarità" che gestisce senza problemi anche gli attributi per gli elementi.

La classe (il cui codice trovate allegato a questo articolo) è una class che contiene due metodi statici che possono essere usati per la conversione da array a XMl e vice versa, in particolare la classe definisce:

<?php
class ArrayToXML {
  static public
toXml() { // ... }
 
static public toArray() { // ... }
}
?>

oltre ad alcune funzionalità e costanti interne, vediamo come usare questa classe.

Innazitutto andiamo ad aggiungere la nostra classe nel codice che dobbiamo usare e creiamo l'array contenente le informazioni che vogliamo convertire:

<?php
include_once('ArrayToXML.php');

$items = array(
 
'item' => array(
   
// Nodo semplice
   
array(
     
'key1' => 'value1',
     
'key2' => 'value2',
    ),
   
// Nodo con attributi
   
array(
     
'key1' => 'value1',
     
'key2' => 'value2',
     
'attributes'  => array(
       
'attr1' => 'attr_value_1',
       
'attr2' => 'attr_value_2',
      ),
    ),
   
// Nodo semplice
   
array(
     
'key1' => 'value1',
     
'key2' => 'value2',
    ),
   
// Nodo con attributi
   
array(
     
'key1' => 'value1',
     
'key2' => 'value2',
     
'attributes'  => array(
       
'attr1' => 'attr_value_1',
       
'attr2' => 'attr_value_2',
      ),
    ),
  ),
 
// Nodo vuoto con attributi
 
'altro' => array (
   
'attributes'  => array(
       
'attr1' => 'attr_value_1',
       
'attr2' => 'attr_value_2',
    ),
  ),
 
// Attributi della radice
 
'attributes'  => array(
       
'attr1' => 'attr_value_1',
       
'attr2' => 'attr_value_2',
  ),
);
?>

Come potete vedere l'array può essere annidiato su più livelli e può contenere delle chiavi chiamate attributes, che vedremo successivamente, vengono elaborate come attributi del nodo a cui appartengono; è anche possibile fare in modo che vengano creati elementi multipli con lo stesso tag (possibile in XML ma non possibile in PHP) andando a usare un array di elementi con la stessa chiave.

Per convertire il nostro array in XML e vice versa andiamo a usare le funzioni statiche precedentemente dichiarate:

<?php
$xml
= ArrayToXML::toXml($items, 'items');
$array = ArrayToXML::toArray($xml);
?>

nella prima linea convertiamo il nostro array in XML e nel secondo caso convertiamo l'XML in array. La prima chiamata ha un secondo parametro, oltre -ovviamente- all'array che deve essere convertito, che rappresenta il nome del tag padre dell'XML.

Nel caso sia necessario realizzare dei nodi che abbiamo il nome attributes, l'utilizzo della classe così come è ora non lo consente, dobbiamo quindi passare attraverso una piccola modifica del codice della classe principale modificando la riga 14 che contiene:

<?php
const attr_arr_string = 'attributes';
?>

in qualche stringa che non dobbiamo utilizzare come tag (potrebbe anche trattarsi di una strinaga completamente random (io preferisco mantenere la chiave attributes perchè è più parlante), e verranno usate le chiavi degli array contenti questa stringa per la generazione dei nodi degli attributi.

Ovviamente l'operazione di conversione da array a XMl e vice versa restituisce lo stesso oggetto, possiamo verificarlo effettuando la differenza tra i due array:

<?php
echo array_diff($items, $array);
?>

che ci restituisce un array vuoto, ad indicare che non vi sono differenze.

In allegato trovate anche un file di esempio da usare per capire il funzionamento della classe, ma se ci sono domande o richieste di chiarimenti fatevi avanti.

AllegatoDimensione
Classe ArrayToXML4.21 KB
Codie di esempio1.62 KB

Altri contenuti che potrebbero interessarti

  • SASS per i CSS con Compass (in ruby)
    Come indicato nell'articolo precedente abbiamo visto la comodità di usare un metalinguaggio per i CSS come SASS. Ovviamente i browser non sono in grado di utilizzare direttamente questi file, ma necessitano di ricevere del codice CSS standard. Questa operazione (NdA:la conversione da SASS a CSS)...
  • Nello sviluppo di siti web è preferibile operare in locale e trasferire il tutto sul server remoto solo una volta che si è ottimizzata la configurazione per lo scopo che ci si è prefissi. Ciò permette di avere una maggior velocità poiché non è necessario operare sul server trasferendo i file ogni...
  • SASS per i CSS
    I CSS sono uno degli elementi che nel corso degli anni, nel settore del web, si sono meno evoluti dal pundo ti vista della struttura utilizzata. Nelle corso delle diverse versioni sono state aggiunge solo proprietà e selettori nuovi. Probabilmente penserete: Se non sono cambiati tantomeglio, evito...
  • Pagina di ricerca con filtri dinamici nelle views
    Le viste sono uno strumento estremamente potente e permettono di andare ad elaborare le informazioni creando degli elementi (pagine, blocchi, ...) di presentazione. La possibilità di usare dei filtri esposti ne fa degli strumenti adatti alla creazione di strumenti di ricerca dei contenuti. L'...

Commenti

Ritratto di Pinolo

Riguardo il codice "bello":

Riguardo il codice "bello": in genere guardo il codice con Firefox, che mi mostra correttamente la struttura, ma per esempio toglie alcuni caratteri "vuoti", come i LF a fine campo, che in questo caso a me serviva controllare. In effetti, la classe a me serviva per creare XML da passare a cose non-web, di qui esigenze leggermente diverse.

Altra cosa che ho verificato e che a mio parere andrebbe modificata:

<?php
$ann_ar
['j_immagine'] = array('attributes' => array('href' => 'file:///Users/utente/Desktop/Links/'. $fileimmagine), $fileimmagine);
?>

Questa istruzione secondo me dovrebbe produrre questo XML:

<j_immagine href="file:///Users/utente/Desktop/Links/alfa_copia_di_p4118783_2.jpg">alfa_copia_di_p4118783_2.jpg</j_immagine>

invece viene generato questo:

<j_immagine href="file:///Users/utente/Desktop/Links/alfa_copia_di_p4118783_2.jpg"><j_immagine>alfa_copia_di_p4118783_2.jpg</j_immagine></j_immagine>

In pratica, quando si usano gli attributi, se oltre agli attributi si inserisce un contenuto del tag, viene creato un tag contenuto nel primo e suo omonimo.

Ritratto di mavimo

Per la parte "abbelimento", ok.

Per quanto riguarda il bug che hai rilevato, grazie, vedo di indagare il problema.

Stavo anche pensando di modificare la regola che identifica il tag che assegna gli attributi, purtroppo in alcuni casi devo usare il tag attributes, e succedono un pò di casini.. cosa ne pensi di #attributes usando la logica che puoi ben immaginare? :D
In teoria non possono esistere tag che cominciano con #.. cosa ne pensate?

Ritratto di Pinolo

Sì, direi che un simbolo come

Sì, direi che un simbolo come prefisso è una soluzione ottimale

Ritratto di Pinolo

Ottimo, grazie mille

L'ho usato oggi e funziona esattamente come spiegato.
2 cose potrebbero migliorare ulteriormente.

  • la conversione dei caratteri in entità HTML potrebbe essere opzionale (un parametro da passare)
  • una ulteriore opzione (oltre all'aggiunta di codice), potrebbe dare in output XML "pretty". Ho provato alcuni degli script che ho trovato in giro, ma nessuno riesce ad "abbellire" il codice buttato fuori dalla tua classe.
Ritratto di mavimo

Ciao

Ok per l'escaping delle entità HTML è in lavorazione la seconda versione dove questa funzionalità è già presente.

Per la "bellezza" del codice XML credo che non la implmenterò perché porta ad una complessità del codice generato che non giustifica il tempo speso nell'implementazione, inoltre questa classe la utilizzo per generare degli XML che vengono veicolati sul web, quindi sono tutti byte buttati via :)

Scherzi a parte io ho provato von un paio di visualizzatori e il codice viene formattato bene, con che codice hai provato tu?

Invia nuovo commento





  • Elementi HTML permessi: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <img> <h2> <h3> <h4> <table> <thead> <tbody> <tr> <th> <td>
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Linee e paragrafi vanno a capo automaticamente.
  • Indirizzi web o e-mail vengono trasformati in link automaticamente

Maggiori informazioni sulle opzioni di formattazione.



Condividi contenuti