php simpleXMLElement to array:null value

时间:2013-02-26 15:01:59

标签: php xml associative-array

我有以下XML:

<account>
    <id>123</id>
    <email></email>
    <status>ACTIVE</status>
</account>

我希望将它作为数组变量。因此我用$xml = simplexml_load_file()阅读了它。将simpleXMLElement转换为关联数组的最简单方法是使用:json_decode(json_encode((array) $xml),1);

来研磨它

问题在于我不希望将email键作为空数组,而是作为NULL值。作为SimpleXMLElement,它看起来像:

public 'email' => 
    object(SimpleXMLElement)[205]

而在数组中它看起来像:

'email' => 
    array (size=0)
      empty

我想得到:

'email' => NULL

实现这一点的唯一方法我想到的是遍历所有元素并用空值替换空数组。问题是我的XML更大(上面只是解释问题)而且我必须迭代很多XML元素(这将是手工工作 - 我正在寻找一些自动化的东西)。也许我在其中一个函数中缺少一些选项...或者可能还有另一个技巧可以做到这一点?

3 个答案:

答案 0 :(得分:6)

我无法添加评论,但我认为这对您有用,它应该比正则表达式或循环更快:

//after you json_encode, before you decode
$str = str_replace(':[]',':null',json_encode($array));

JSON中的空数组由“[]”表示。有时,数组被解析为对象,在这种情况下(或作为后备),您也可以替换“:{}”。

答案 1 :(得分:1)

一个空的SimpleXMLElement object将被强制转换为一个空数组。您可以通过从SimpleXMLElement扩展并实现JsonSerializable interface并将其强制转换为 null 来进行更改。

/**
 * Class JsonXMLElement
 */
class JsonXMLElement extends SimpleXMLElement implements JsonSerializable
{

    /**
     * Specify data which should be serialized to JSON
     *
     * @return mixed data which can be serialized by json_encode.
     */
    public function jsonSerialize()
    {
        $array = array();

        // json encode attributes if any.
        if ($attributes = $this->attributes()) {
            $array['@attributes'] = iterator_to_array($attributes);
        }

        // json encode child elements if any. group on duplicate names as an array.
        foreach ($this as $name => $element) {
            if (isset($array[$name])) {
                if (!is_array($array[$name])) {
                    $array[$name] = [$array[$name]];
                }
                $array[$name][] = $element;
            } else {
                $array[$name] = $element;
            }
        }

        // json encode non-whitespace element simplexml text values.
        $text = trim($this);
        if (strlen($text)) {
            if ($array) {
                $array['@text'] = $text;
            } else {
                $array = $text;
            }
        }

        // return empty elements as NULL (self-closing or empty tags)
        if (!$array) {
            $array = NULL;
        }

        return $array;
    }
}

然后告诉simplexml_load_string返回JsonXMLElement类的对象

$xml = <<<XML
<account>
   <id>123</id>
   <email></email>
   <status>ACTIVE</status>
</account>
XML;

$obj = simplexml_load_string($xml, 'JsonXMLElement');

// print_r($obj);

print json_encode($obj, true);

/*
 * Output...
{
   "id": 123,
   "email": null,
   "status": "ACTIVE"
}
*/

信用:hakre

答案 2 :(得分:0)

检查性能srt_replace与递归循环

  • 迭代:100000
  • XML lenght :4114 bytes
  • 初始化脚本时间:~1.2264486691986E-6秒
  • Json编码/解码时间:~9.8956169957496E-5秒
  • str_replace 平均时间: 0.00010692856433176
  • 递归循环平均时间: 0.00011844366600813

str_replace快速开启~0.00001秒。在许多电话

中,差异会很明显