XML в ассоциативный массив с использованием PHP

Может ли кто-нибудь помочь с преобразованием данных из XML-документа в ассоциативный массив? Я сталкиваюсь с проблемами, учитывая, что структура XML – это своего рода 3D, а массив больше 2D-структуры (прошу простить мою отсутствие правильной терминологии). Элементы XML имеют атрибуты, дети и внуки (но я никогда не знаю их имен), поэтому я решил, что попытаюсь сделать ключ в массиве конкатенацией каждого имени дочернего / атрибута и значения, равного, Значение. Проблема в том, что мне нужно имя атрибута и значение как часть ключа конкатенированного массива, чтобы сделать его уникальным …

Например:

<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> 

В идеале следует дать:

 [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' 

Но я получаю этот результат:

 [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' 

Так что ключ [Computer-id] не уникален. Я использую рекурсивную функцию для чтения значений, но не могу понять, как получить имя атрибута и значение атрибута в имени подчиненных ключей … (Кстати, для этого есть веская причина казалось бы, нелогичная задача!) Любая помощь будет принята с благодарностью …

Вот функция, которая «сглаживает» данные XML после того, как она была прочитана в многомерном массиве. Я не уверен, что я собираюсь сделать это правильно!

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

Solutions Collecting From Web of "XML в ассоциативный массив с использованием PHP"

Одним из примеров может быть:

 $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 = array(); foreach ($xpath->query('//*[count(*) = 0]') as $node) { $path = array(); $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('/', array_reverse($path))] = $val; } print_r($result); 

Вывод:

 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 ) 

Это не совсем то, что вы ищете, но это начало и его можно легко настроить, чтобы дать разные результаты.

Это работало отлично для меня, и это было просто.

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

Прочитайте xml в объект DOM, пропустите его, сохраните результаты в массив. Это просто.

вот моя функция для создания связанного массива, полученного из

Рекурсивное преобразование из SimpleXMLObject в массив

 function xml2assoc($obj, &$arr) { $children = $obj->children(); foreach ( $children as $elementName => $node ) { if (!isset($arr[$elementName])) { $arr[$elementName] = array(); } $temp = array(); $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 = array(); xml2assoc($dom, $arr); print_r($arr); 

сгенерированный массив:

 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 ) ) ) ) ) ) ) 

Простые массивы могут быть 2d, но многомерные массивы могут очень легко копировать иерархическую структуру, такую ​​как xml.

Google «ассоциативный многомерный массив php» для получения дополнительной информации.

Однако, как уже было сказано, PHP имеет встроенный синтаксический анализатор xml, поэтому не должно возникнуть необходимости повторно создавать xml внутри массива, не говоря уже о том, чтобы сгладить его до простого массива.

В PHP структура массива должна выглядеть примерно так:

 $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"; 

и т.д…