Immagino di essere un po 'in ritardo alla festa, ma ho scritto una piccola funzione per svolgere questo compito. Si occupa anche degli attributi, del contenuto del testo e anche se più nodi con lo stesso nome-nodo sono fratelli.
Dichiarazione di
non responsabilità: non sono un nativo di PHP, quindi ti preghiamo di sopportare semplici errori.
function xml2js($xmlnode) {
$root = (func_num_args() > 1 ? false : true);
$jsnode = array();
if (!$root) {
if (count($xmlnode->attributes()) > 0){
$jsnode["$"] = array();
foreach($xmlnode->attributes() as $key => $value)
$jsnode["$"][$key] = (string)$value;
}
$textcontent = trim((string)$xmlnode);
if (count($textcontent) > 0)
$jsnode["_"] = $textcontent;
foreach ($xmlnode->children() as $childxmlnode) {
$childname = $childxmlnode->getName();
if (!array_key_exists($childname, $jsnode))
$jsnode[$childname] = array();
array_push($jsnode[$childname], xml2js($childxmlnode, true));
}
return $jsnode;
} else {
$nodename = $xmlnode->getName();
$jsnode[$nodename] = array();
array_push($jsnode[$nodename], xml2js($xmlnode, true));
return json_encode($jsnode);
}
}
Esempio di utilizzo:
$xml = simplexml_load_file("myfile.xml");
echo xml2js($xml);
Esempio di input (myfile.xml):
<family name="Johnson">
<child name="John" age="5">
<toy status="old">Trooper</toy>
<toy status="old">Ultrablock</toy>
<toy status="new">Bike</toy>
</child>
</family>
Esempio di output:
{"family":[{"$":{"name":"Johnson"},"child":[{"$":{"name":"John","age":"5"},"toy":[{"$":{"status":"old"},"_":"Trooper"},{"$":{"status":"old"},"_":"Ultrablock"},{"$":{"status":"new"},"_":"Bike"}]}]}]}
Abbastanza stampato:
{
"family" : [{
"$" : {
"name" : "Johnson"
},
"child" : [{
"$" : {
"name" : "John",
"age" : "5"
},
"toy" : [{
"$" : {
"status" : "old"
},
"_" : "Trooper"
}, {
"$" : {
"status" : "old"
},
"_" : "Ultrablock"
}, {
"$" : {
"status" : "new"
},
"_" : "Bike"
}
]
}
]
}
]
}
Stranezze da tenere a mente:
diversi tag con lo stesso tagname possono essere fratelli. Molto probabilmente altre soluzioni lasceranno cadere tutto tranne l'ultimo fratello. Per evitare questo ogni singolo nodo, anche se ha solo un figlio, è un array che contiene un oggetto per ogni istanza del tagname. (Vedi più "" elementi nell'esempio)
Anche l'elemento radice, di cui solo uno dovrebbe esistere in un documento XML valido, viene archiviato come array con un oggetto dell'istanza, solo per avere una struttura dati coerente.
Per poter distinguere il contenuto del nodo XML e gli attributi XML, gli attributi di ciascun oggetto sono memorizzati in "$" e il contenuto nel figlio "_".
Modifica:
ho dimenticato di mostrare l'output per i dati di input del tuo esempio
{
"states" : [{
"state" : [{
"$" : {
"id" : "AL"
},
"name" : [{
"_" : "Alabama"
}
]
}, {
"$" : {
"id" : "AK"
},
"name" : [{
"_" : "Alaska"
}
]
}
]
}
]
}
var_dump
funziona benissimo.)