Преобразование массива PHP в XML? - PullRequest
2 голосов
/ 31 июля 2009

скажем, у меня есть такой массив:

<?php
$colors=array();

$colors[0]['id']=1;
$colors[0]['color']='blue';


$colors[1]['id']=2;
$colors[1]['color']='green';

......
?>

Какой самый простой способ преобразовать весь массив в XML?

Ответы [ 4 ]

0 голосов
/ 31 мая 2017

Мне понадобилось много часов, чтобы сделать это. Я действительно не могу поверить, что в PHP нет функции, которая делает это за вас. Во всяком случае, я надеюсь, что это кому-то полезно. Наслаждайтесь!

<?php
class Xml
{
  public function getXmlFromArray($value, \SimpleXMLElement &$xmlElement, $entity, $starting = null)
{

    $handleValue = function($value){
        $entityHandler = $this->getEntityHandler();
        if($entityHandler && $entityHandler instanceof \Closure){
            $value = $entityHandler($value);
        }
        if(is_string($value)){
            $value = htmlspecialchars($value);
        }
        return $value;
    };
    $addChild = function($name, $value, &$subNode = null)use(&$xmlElement, $handleValue, $entity){
        if(is_array($value)){
            if(!$subNode instanceof \SimpleXMLElement){
                $currentKey = key($value);
                $initialValue = null;
                if(is_numeric($currentKey)){
                    if(!is_array($value[$currentKey])){
                        $initialValue = $value[$currentKey];
                        unset($value[$currentKey]);
                    }
                }
                $subNode = $xmlElement->addChild($this->cleanXmlTagName($name), $initialValue);
            }
            $this->getXmlFromArray($handleValue($value), $subNode, $name);
        } else {
            $xmlElement->addChild($this->cleanXmlTagName($name), $handleValue($value));
        }
    };

    if(is_array($value))
    {
        if(is_numeric(key($value))){
            $setSubNodePrimitiveValue = function($value)use(&$xmlElement, $entity, $handleValue){
                $value = $handleValue($value);
                $children = $xmlElement->children();
                $children[] = $value;
            };
            foreach ($value as $item)
            {
                if(!is_array($item)){
                    $setSubNodePrimitiveValue($item);
                } else {
                    if($starting === true){
                        $addChild($entity, $item);
                    } else {
                        $addChild($entity, $item, $xmlElement);
                    }
                }
            }
        } else {
            foreach ($value as $subEntity => $subEntityItem)
            {
                if(is_array($subEntityItem) && is_array(current($subEntityItem)) && is_numeric(key($subEntityItem))){
                    $this->getXmlFromArray($subEntityItem, $xmlElement, $subEntity, true);
                    continue;
                }
                $addChild($subEntity, $subEntityItem);
            }
        }
    } else {
        $xmlElement->addChild($this->cleanXmlTagName($entity), $handleValue($value));
    }
}

public function cleanXmlTagName(string $tagName)
{
    if(is_numeric($tagName[0])){
        $tagName = '_'.$tagName;
    }
    return preg_replace('/[^A-Za-z0-9.\-_]/', '_', $tagName);
}

  /**
   * @param array $array
   * @param string $openingTag
   * @param string $entity
   * @param string $nameSpace
   * @param bool $isPrefixed
   * @return \SimpleXMLElement
   */
  public function generateXmlFromArray(array $array, string $openingTag, string $entity, $nameSpace = '', $isPrefixed = false)
  {
      $xmlString = '<'.$openingTag.'></'.$openingTag.'>';
      $xml = new \SimpleXMLElement($xmlString, LIBXML_NOERROR, false, $nameSpace, $isPrefixed);
      $this->getXmlFromArray($array, $xml, $entity, true);
      return $xml;
  }

  /**
   * @param string $xml
   * @return bool
   */
  public function validateXml(string $xml)
  {
      $dom = new \DOMDocument();
      $dom->loadXML($xml);
      return $dom->validate();
  }

  public function loadXmlPathAsArray(string $xmlPath)
  {
      $xml   = simplexml_load_file($xmlPath);
      $array = json_decode(json_encode($xml), TRUE);
      return (array)$array;
  }

  /**
   * @param string $xmlString
   * @return array
   */
  public function loadXmlStringAsArray(string $xmlString)
  {
      $array = (array) @simplexml_load_string($xmlString);
      if(!$array){
          $array = (array) @json_decode($xmlString, true);
      } else{
          $array = (array)@json_decode(json_encode($array), true);
      }
      return $array;
  }

  /**
   * @param string $xmlString
   * @return \SimpleXMLElement
   */
  public function loadXmlString(string $xmlString)
  {
      return @simplexml_load_string($xmlString);
  }
}
0 голосов
/ 19 июля 2011

Если вам также нужна поддержка атрибутов для преобразования массива в XML, вы можете использовать эту реализацию: http://www.lalit.org/lab/convert-php-array-to-xml-with-attributes/

Для поддержки атрибутов требуется, чтобы вы создали свой массив определенным образом. Для xml без атрибутов вы можете напрямую передать любой массив в функцию и получить XML

0 голосов
/ 03 января 2013

Вы можете создать себе простую функцию, которая просто выводит ее. Например, передача массива с элементами в функцию и указание имени родительского элемента (корневого элемента документа) и имени каждого элемента.

Я предполагаю colors для родителя и color для каждого элемента.

Я также предположил, что именованные ключи являются дочерними элементами color элементов:

function xml_from_indexed_array($array, $parent, $name) {

    echo '<?xml version="1.0"?>', "\n";
    echo "<$parent>\n";
    foreach ($array as $element) {
        echo "  <$name>\n";
        foreach ($element as $child => $value) {
            echo "    <$child>$value</$child>\n";
        }
        echo "  </$name>\n";
    }
    echo "</$parent>\n";
}

Как видите, это довольно просто, просто перебирая все элементы.

Пример использования:

<?php
$colors = array();

$colors[0]['id']    = 1;
$colors[0]['color'] = 'blue';

$colors[1]['id']    = 2;
$colors[1]['color'] = 'green';

xml_from_indexed_array($colors, 'colors', 'color');

Пример вывода:

<?xml version="1.0"?>
<colors>
  <color>
    <id>1</id>
    <color>blue</color>
  </color>
  <color>
    <id>2</id>
    <color>green</color>
  </color>
</colors>

Если у вас есть более сложные структуры массивов, которые более глубоко вложены, вы можете решить эту проблему рекурсивным способом. Некоторые связанные вопросы:

0 голосов
/ 31 июля 2009

Некоторые рабочие примеры для рассматриваемых данных на месте: https://stackoverflow.com/a/14143759/367456

Оригинальный ответ следует:

Взгляните на эти заранее определенные реализации:

http://snipplr.com/view/3491/convert-php-array-to-xml-or-simple-xml-object-if-you-wish/

http://vantulder.net/f2o/notities/arraytoxml/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...