Задача проста: конвертировать php массив любой вложенности в xml документ. Готового решения в самом языке так и не обнаружил.  Есть функции которые конвертируют из массива в JSON и обратно, а вот в XML нет. Я конечно заядлый велосипедостроитель, но был не тот случай - время поджимало а проект надо было завершать. Ну что же немного поискав на просторах сети нашел нужное решение 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class ArrayToXML
{
  /**
   * Функция конвертации массива в XML объект
   * На вход подается мульти вложенный массив, на выходе получается с помощью рекурсии валидный xml
   *
   * @param array $data
   * @param string $rootNodeName - корень вашего xml.
   * @param SimpleXMLElement $xml - используется рекурсивно
   * @return string XML
   */
  public static function toXml($data, $rootNodeName = 'data', $xml=null)
  {
    // включить режим совместимости, не совсем понял зачем это но лучше делать
    if (ini_get('zend.ze1_compatibility_mode') == 1)
    {
      ini_set ('zend.ze1_compatibility_mode', 0);
    }
  
    if ($xml == null)
    {
      $xml = simplexml_load_string("<?xml version=\"1.0\" encoding=\"utf-8\"?><$rootNodeName />");
    }
  
    //цикл перебора массива
    foreach($data as $key => $value)
    {
      // нельзя применять числовое название полей в XML
      if (is_numeric($key))
      {
        // поэтому делаем их строковыми
        $key = "unknownNode_". (string) $key;
      }
  
      // удаляем не латинские символы
      $key = preg_replace('/[^a-z0-9]/i', '', $key);
  
      // если значение массива также является массивом то вызываем себя рекурсивно
      if (is_array($value))
      {
        $node = $xml->addChild($key);
        // рекурсивный вызов
        ArrayToXML::toXml($value, $rootNodeName, $node);
      }
      else
      {
        // добавляем один узел
                                $value = htmlentities($value);
        $xml->addChild($key,$value);
      }
  
    }
    // возвратим обратно в виде строки  или просто XML-объект
    return $xml->asXML();
  }
}

Использовать это чудо можно так 

1
2
$data = array('color'=>'red','colors'=>array('#fff','#ddd','#eee'));
echo ArrayToXML::toXML($data);

В итоге на выходе получаем

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<data>
 <color>red</color>
 <colors>
  <unknownNode>#fff</unknownNode>
  <unknownNode>#ddd</unknownNode>
  <unknownNode>#eee</unknownNode>
 </colors>
</data>

Вот по настоящему полезный скрипт

Оставлять комментарии могут только зарегистрированные пользователи

Комментарии  

Гость
# Гость 05.01.2011 22:47
Клева =) добавил в закладку
Sinyagin
# Sinyagin 02.02.2011 14:26
Чето глюки с кодировкой:(
Вано
# Вано 15.03.2011 15:32
А на выходе появляется html или объект?
Leroy
# Leroy 16.03.2011 16:42
ну там написано же
$xml->asXML();
возвращает строку, если хотите чисто $xml то просто убираем метод asXML
Андрей
# Андрей 18.04.2011 17:49
Спасибо, как раз нужно
Igor
# Igor 26.04.2011 00:18
еба, а что вернет $data['color']?. Шизофрения какая-то.
Leroy
# Leroy 26.04.2011 01:38
Поправил
Сергей
# Сергей 17.10.2011 19:26
Отличная штука - дописал чучуть чтобы можно было атрибуты добавлять


// если значение массива также является массивом то вызываем себя рекурсивно
if (is_array($value) and $key{1} != "@")
{
$node = $xml->addChild($key);
// рекурсивный вызов
Xml::arrayToXml($value, $rootNodeName, $node);
}
elseif($key{0} != "@")
{
// добавляем один узел
$value = htmlentities( $value );
$xml->addChild( $key, $value );
}
else
{
$value = htmlentities( $value );
$key = substr($key, 1);
$xml->addAttribute( $key, $value );
}




а вот набор элементов уже не создать




red
blue
yellow

Виталий Фесюра
# Виталий Фесюра 03.05.2017 10:15
я не понял как передавать массив, что бы получить атрибуты. Например для корневого тега я делаю так $rootNodeName = 'DECLAR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instan ce" xsi:noNamespaceSchemaLocation="J1201009.XSD"'. Например, если значение элемента массива пустое (false), то что бы получилось . Заранее благодарю.
Виталий Фесюра
# Виталий Фесюра 03.05.2017 10:16
'""'
Сергей
# Сергей 17.10.2011 19:29
Теги скушал не так =\

Переименовал класс в Xml метод обозвал arrayToXml

На мой взгляд так логичней
sprut
# sprut 19.03.2012 13:22
Скопировал,вставил в редактор, или я дурак или там явная ошибка в 23 строчке

$xml = simplexml_load_string("");
arturgspb
# arturgspb 19.06.2012 20:02
Зачем класс, состоящий из одной функции да и при том статичной - это плохая практика. В вашем случае лучше просто функцию сделать.
Leroy
# Leroy 20.06.2012 14:04
дак я ж не против, дополняем класс, выкладываем в комментах, я обновляю пост, нанимаем секретаршу, спасаем мир
Ilia
# Ilia 29.08.2012 15:32
Использовал ваш класс, спасибо, подправил регулярку, название XML элемента может содержать цифру, а вы их затираете.
Leroy
# Leroy 29.08.2012 21:00
спасибо за сигнал) щас поправим
Leroy
# Leroy 15.04.2013 16:03
Поправил класс