У меня есть массив, который нужно преобразовать в формат xml.
[name] => ABC [email] => email@email.com [phones] => Array ( [phone] => Array ( [0] => Array ( [mobile] => 91454599193 [land] => 9999999 ) [1] => Array ( [mobile] => 54520199193 [land] => 9999999 ) [2] => Array ( [mobile] => 90424249194 [land] => 5555555 ) [3] => Array ( [mobile] => 44224199195 [land] => 8888888 ) ) )
Я хочу, чтобы это было в следующем формате
<name>ABC</name> <email>email@email.com</email> <phones> <phone> <mobile>545450199193</mobile> <land>9999999</land> </phone> <phone> <mobile>575199193</mobile> <land>9999999</land> </phone> </phones>
Пожалуйста, помогите мне ….
Это моя функция, я написал таким образом. Проблема, с которой я столкнулся, заключается в том, что индекс, содержащий номера, должен отображать текст в узле XML. Пример: – Ниже в телефоне имеется индекс [0], [1]. Я хочу, чтобы [0], [1] был заменен на <phone>
на моей странице XML.
function array_to_xml($value, &$xml_student_info) { foreach($value as $key => $value) { if(is_array($value)) { if(!is_numeric($key)){ $subnode = $xml_student_info->addChild("$key"); array_to_xml($value, $subnode); } else{ array_to_xml($value, $xml_student_info); } } else { $xml_student_info->addChild("$key","$value"); } } }
Вы можете решить свою проблему, используя рекурсию. Рекурсия отлично справляется с вложенными данными.
Вы делаете это, создавая единую функцию, добавляющую значение к родительскому элементу XML.
Затем эта функция вызывает себя в случае обнаружения вложенных данных. Затем он добавит дочерний элемент к родительскому, и сам вызов будет с новым элементом, добавленным как родительский.
Если данные, которые нужно добавить, это просто строка, она все равно создаст дочерний элемент, но добавит строковое значение напрямую и уйдет. Это листовые узлы, не выходящие наружу.
Функция добавления затем должна только считывать данные, которые вы анализируете, и выяснить, с какими из четырех случаев следует обращаться:
Для этого ответа я подумал, что было бы неплохо попробовать это с анонимной функцией. Чтобы получить его рекурсивный, он должен ссылаться сам. Затем он может быть обернут внутри другой функции, которая позволит создавать и импортер для SimpleXMLElement
который позволяет легко создавать XML. Обернутый еще один раз позволил бы даже передавать XML как строку, однако я сохраняю это для внешнего, чтобы сделать использование понятным:
require('inc/simplexml_pretty_print.php'); $xml = new SimpleXMLElement('<root/>'); $importer = $createArrayImporter($xml); echo simplexml_pretty_print($importer($array));
В этом примере $array
– это массив из вашего вопроса. Он содержит те четыре случая, которые обрабатываются здесь в функции $add
которая будет возвращена в другую анонимную функцию при вызове $createArrayImporter()
в примере выше.
Прежде чем приступить к работе, давайте рассмотрим входной массив:
$array = [ 'name' => 'ABC', 'email' => 'email@email.com', 'phones' => [ 'phone' => [ [ 'mobile' => '9000199193', 'land' => ' 9999999 ', ], [ 'mobile' => '9000199193', 'land' => ' 9999999 ', ], [ 'mobile' => '9000199194', 'land' => ' 5555555 ', ], [ 'mobile' => '9000199195', 'land' => ' 8888888 ', ], ], ], ];
И результат этого создает:
<?xml version="1.0"?> <root> <name>ABC</name> <email>email@email.com</email> <phones> <phone> <mobile>9000199193</mobile> <land> 9999999 </land> </phone> <phone> <mobile>9000199193</mobile> <land> 9999999 </land> </phone> <phone> <mobile>9000199194</mobile> <land> 5555555 </land> </phone> <phone> <mobile>9000199195</mobile> <land> 8888888 </land> </phone> </phones> </root>
И как рекурсивная функция:
$add = function (SimpleXMLElement $subject, $key, $value) use (&$add)
Субъект – это элемент XML для добавления данных, ключ – это ключ в массиве, а также значение, которое может быть или не быть вложенным.
Поэтому, учитывая наиболее прямолинейный случай, ваш ключевой (все индексы массива являются строками) массив должен быть добавлен к корневому элементу.
case $isKeyed: foreach ($value as $oneof_key => $oneof_value) { $add($subject, $oneof_key, $oneof_value); }
Это передаст значения вдоль вложенных значений. Например, сначала на следующем уровне [name] => ABC
, поэтому строка с ключом:
case $isString && $hasKey: return $subject->addChild($key, $value);
Это просто добавляет дочерний элемент со строковым значением, названным в качестве ключа.
Следующий случай
[phones] => Array ( [phone] => Array ( ...
Это массив с ключом для именованного элемента:
case $isKeyed && $hasKey: $subject = $subject->addChild($key); // fall-through intended
Он должен добавить свой собственный ключ как дочерний элемент, сопоставимый с $isString && $hasKey
, но затем необходимо обработать его значение массива дальше. Который также является вложенным случаем массива с ключом, который имеет индексированные дочерние элементы (0-N как индексы), так что может быть добавлено более одного элемента с тем же именем:
case $isKeyed: foreach ($value as $oneof_key => $oneof_value) { $add($subject, $oneof_key, $oneof_value); } return true;
Это произойдет в этом случае, а также создаст четвертый случай для массива с ключом, который не имеет ключа, а просто пронумерован.
Вот почему я написал, что его три с половиной случая, два последних разделяют между собой некоторые части.
Обертка этого внутри крышки делает это более доступным, о чем я расскажу только в небольшом примере здесь:
$createArrayImporter = function (SimpleXMLElement $subject) { $add = function (SimpleXMLElement $subject, $key, $value) use (&$add) { ... }; return function (Array $array) use ($subject, $add) { $add($subject, null, $array); return $subject; }; };
Так что это может уйти. Вы можете прочитать полный код в моем Gist .
Вы найдете аналогичный пример, но mdes object ориентирован в следующем ответе, который также решает его посредством рекурсии:
Формат массива, даже если он может выглядеть похожим, на самом деле отличается от вашего.
И для большего количества указателей есть:
Что касается различных типов массивов для преобразования XML.
Проблема в том, что вы не можете иметь одинаковые ключи в одном массиве или объекте. В случае simplexml есть объект, в котором сохраняется xml. Решение состоит в том, чтобы самостоятельно создать xml.