PHP-массив для преобразования xml даже для вложенных данных

У меня есть массив, который нужно преобразовать в формат 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"); } } } 

Solutions Collecting From Web of "PHP-массив для преобразования xml даже для вложенных данных"

Вы можете решить свою проблему, используя рекурсию. Рекурсия отлично справляется с вложенными данными.

Вы делаете это, создавая единую функцию, добавляющую значение к родительскому элементу XML.

Затем эта функция вызывает себя в случае обнаружения вложенных данных. Затем он добавит дочерний элемент к родительскому, и сам вызов будет с новым элементом, добавленным как родительский.

Если данные, которые нужно добавить, это просто строка, она все равно создаст дочерний элемент, но добавит строковое значение напрямую и уйдет. Это листовые узлы, не выходящие наружу.

Функция добавления затем должна только считывать данные, которые вы анализируете, и выяснить, с какими из четырех случаев следует обращаться:

  1. Просто добавьте новый элемент со строковым значением (строка для именованного элемента)
  2. Добавьте несколько новых элементов с тем же именем (0-n индексированный массив для именованного элемента)
  3. Добавьте новых детей, а затем добавьте туда N новых детей (массив с ключом для именованного элемента)
  4. Добавьте N новых детей в родительский (массив с ключом для пронумерованного (неименованного) элемента)

Для этого ответа я подумал, что было бы неплохо попробовать это с анонимной функцией. Чтобы получить его рекурсивный, он должен ссылаться сам. Затем он может быть обернут внутри другой функции, которая позволит создавать и импортер для 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 ориентирован в следующем ответе, который также решает его посредством рекурсии:

  • php: экспортировать массив в xml-проблему

Формат массива, даже если он может выглядеть похожим, на самом деле отличается от вашего.

И для большего количества указателей есть:

  • Как преобразовать массив в SimpleXML

Что касается различных типов массивов для преобразования XML.

Проблема в том, что вы не можете иметь одинаковые ключи в одном массиве или объекте. В случае simplexml есть объект, в котором сохраняется xml. Решение состоит в том, чтобы самостоятельно создать xml.