XML in arrays associativo utilizzando PHP

Qualcuno può aiutare con la conversione di dati da un documento XML in un arrays associativo? Mi sto imbattendo in problemi dato che la struttura XML è una specie di 3D e l'arrays è più di una struttura 2D (per favore perdona la mia mancanza di terminologia corretta in tutto). Gli elementi XML hanno attributi, figli e nipoti (ma non conosco mai i loro nomi), quindi ho pensato di provare a rendere la chiave nell'arrays una concatenazione di each nome figlio / attributo e il valore uguale a, beh, il valore. Il problema è che ho bisogno del nome e del valore dell'attributo come parte della chiave dell'arrays concatenato per renderlo unico …

Per esempio:

<Computer id="1"> <OS> <Name>Linux</Name> <Age>Older than me</Age> </OS> </Computer> <Computer id="2"> <OS> <Name>Windows</Name> <Age>Not so much</Age> </OS> </Computer> 

Dovrebbe idealmente dare:

 [Computer-id-1-OS-Name] = 'Linux' [Computer-id-1-OS-Age] = 'Older than me' [Computer-id-2-OS-Name] = 'Windows' [Computer-id-2-OS-Age] = 'Not so much' 

Ma sto ottenendo questo risultato:

 [Computer-id] = '1' [Computer-OS-Name] = 'Linux' [Computer-OS-Age] = 'Older than me' [Computer-id] = '2' [Computer-OS-Name] = 'Windows' [Computer-OS-Age] = 'Not so much' 

In modo che il tasto [ID computer] non sia univoco. Sto usando una function ricorsiva per leggere i valori, ma non riesco a capire come get il nome dell'attributo e il valore dell'attributo nel nome delle chiavi subordinate … (Tra l'altro c'è una buona ragione per farlo task apparentemente illogico!) Qualsiasi aiuto sarebbe molto apprezzato …

Ecco la function che "appiattisce" i dati XML dopo che sono stati letti in una matrix multidimensionale. Non sono sicuro che lo farò nel modo giusto!

 function flattenArray ($arrays, $baseName = NULL) { reset($arrays); while (list ($key, $value) = each($arrays)) { $outKey = $key . "-"; if (is_arrays($value)) { flattenArray($value, $baseName . $outKey); } else { $finalKey = $baseName . rtrim($outKey, '-'); $finalValue = $value; echo "$finalKey = $finalValue\n"; } } } 

Un esempio potrebbe essere:

 $dom = new DOMDocument; $dom->loadXML( '<root> <Computer id="1"> <OS> <Name>Linux</Name> <Age>Older than me</Age> </OS> </Computer> <Computer id="2"> <OS> <Name>Windows</Name> <Age>Not so much</Age> </OS> </Computer> </root>' ); $xpath = new DOMXPath($dom); $result = arrays(); foreach ($xpath->query('//*[count(*) = 0]') as $node) { $path = arrays(); $val = $node->nodeValue; do { if ($node->hasAttributes()) { foreach ($node->attributes as $attribute) { $path[] = sprintf('%s[%s]', $attribute->nodeName, $attribute->nodeValue); } } $path[] = $node->nodeName; } while ($node = $node->parentNode); $result[implode('/', arrays_reverse($path))] = $val; } print_r($result); 

Produzione:

 Array ( [#document/root/Computer/id[1]/OS/Name] => Linux [#document/root/Computer/id[1]/OS/Age] => Older than me [#document/root/Computer/id[2]/OS/Name] => Windows [#document/root/Computer/id[2]/OS/Age] => Not so much ) 

Questo non è esattamente quello che stai cercando, ma è un inizio e può essere facilmente ottimizzato per dare risultati diversi.

Questo ha funzionato alla grande per me, ed è stato semplice.

 $ob = simplexml_load_file('test.xml'); $json = json_encode($ob); $arrays = json_decode($json, true); 

Leggi l'xml in un object DOM, passa attraverso di esso, salva i risultati in un arrays. È così semplice

ecco la mia function per generare arrays associato, derivato da

Cast ricorsivo da SimpleXMLObject a Array

 function xml2assoc($obj, &$arr) { $children = $obj->children(); foreach ( $children as $elementName => $node ) { if (!isset($arr[$elementName])) { $arr[$elementName] = arrays(); } $temp = arrays(); $attributes = $node->attributes(); foreach ( $attributes as $attributeName => $attributeValue ) { $attribName = strtolower(trim((string) $attributeName)); $attribVal = trim((string) $attributeValue); $temp[$attribName] = $attribVal; } $text = (string) $node; $text = trim($text); if (strlen($text) > 0) { $temp ['text='] = $text; } $arr[$elementName][] = $temp; $nextIdx = count($arr[$elementName]); xml2assoc($node, $arr[$elementName][$nextIdx - 1]); } return; } $xml = '<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[news]]></MsgType> <ArticleCount>2</ArticleCount> <Articles> <item> <Title><![CDATA[title1]]></Title> <Description><![CDATA[description1]]></Description> <PicUrl><![CDATA[picurl]]></PicUrl> <Url><![CDATA[url]]></Url> </item> <item> <Title><![CDATA[title]]></Title> <Description><![CDATA[description]]></Description> <PicUrl><![CDATA[picurl]]></PicUrl> <Url><![CDATA[url]]></Url> </item> </Articles> </xml> '; $dom = new SimpleXMLElement($xml); $arr = arrays(); xml2assoc($dom, $arr); print_r($arr); 

matrix generata:

 Array ( [ToUserName] => Array ( [0] => Array ( [text=] => toUser ) ) [FromUserName] => Array ( [0] => Array ( [text=] => fromUser ) ) [CreateTime] => Array ( [0] => Array ( [text=] => 12345678 ) ) [MsgType] => Array ( [0] => Array ( [text=] => news ) ) [ArticleCount] => Array ( [0] => Array ( [text=] => 2 ) ) [Articles] => Array ( [0] => Array ( [item] => Array ( [0] => Array ( [Title] => Array ( [0] => Array ( [text=] => title1 ) ) [Description] => Array ( [0] => Array ( [text=] => description1 ) ) [PicUrl] => Array ( [0] => Array ( [text=] => picurl ) ) [Url] => Array ( [0] => Array ( [text=] => url ) ) ) [1] => Array ( [Title] => Array ( [0] => Array ( [text=] => title ) ) [Description] => Array ( [0] => Array ( [text=] => description ) ) [PicUrl] => Array ( [0] => Array ( [text=] => picurl ) ) [Url] => Array ( [0] => Array ( [text=] => url ) ) ) ) ) ) ) 

Gli arrays semplici possono essere 2d ma gli arrays multidimensionali possono replicare molto facilmente una struttura gerarchica come xml.

'Php associativo multidimensionale di Google' per maggiori informazioni.

Tuttavia, come è già stato detto, PHP ha un parser xml incorporato, quindi non ci dovrebbe essere alcuna necessità di ricreare l'xml all'interno di un arrays in each caso, per non parlare di appiattirlo su un arrays semplice.

All'interno di PHP la struttura dell'arrays dovrebbe assomigliare a questa:

 $computers["computers"]["computer-1"]["OS"]["Name"] = "Linux"; $computers["computers"]["computer-1"]["OS"]["Age"] = "Older Than Me"; $computers["computers"]["computer-2"]["OS"]["Name"] = "Windows"; $computers["computers"]["computer-2"]["OS"]["Age"] = "Not so much"; 

eccetera…