代码之家  ›  专栏  ›  技术社区  ›  Ali

将PHP数组转换为XML?

  •  2
  • Ali  · 技术社区  · 15 年前

    假设我有一个这样的数组:

    <?php
    $colors=array();
    
    $colors[0]['id']=1;
    $colors[0]['color']='blue';
    
    
    $colors[1]['id']=2;
    $colors[1]['color']='green';
    
    ......
    ?>
    

    将整个数组转换为XML最简单的方法是什么?

    4 回复  |  直到 8 年前
        2
  •  0
  •   Lalit    13 年前

    如果还希望属性支持将数组转换为XML,则可以使用此实现: http://www.lalit.org/lab/convert-php-array-to-xml-with-attributes/

    对于属性支持,它要求您以特定的方式构造数组。对于没有属性的XML,可以直接将任何数组传递给函数并获取XML

        3
  •  0
  •   Community CDub    8 年前

    您可以创建一个简单的函数来输出它。例如,将带有元素的数组传递给函数,并告诉父元素(文档的根元素)的名称和每个元素的名称。

    我假设 colors 为家长和 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>
    

    如果您有更高级的数组结构,并且嵌套更深,那么您可能希望以递归的方式解决这个问题。一些相关问题:

        4
  •  0
  •   kurtbr    8 年前

    我花了好几个小时才这么做。我真的不敢相信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);
      }
    }