php simpleXMLElement到数组:null值


php simpleXMLElement to array: null value

我有以下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

实现这一点的唯一方法是迭代所有元素,并用null值替换空数组。问题是我的XML要大得多(上面只是为了解释这个问题(,我必须迭代很多XML元素(这将是手动的工作——我正在寻找自动的东西(。也许我在其中一个函数中遗漏了一些选项。。。或者可能还有另一个技巧可以做到这一点?

我不能添加注释,但我认为这对你有用,它应该比正则表达式或循环更快:

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

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

一个空的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

检查str_replace与递归循环的性能

  • 迭代次数:100000
  • XML长度:4114字节
  • 初始化脚本时间:约1.2264486691986E-6秒
  • JSON编码/解码时间:~9.8956169957496E-5秒
  • str_replace平均时间:0.00010692856433176
  • 递归循环平均时间:0.000118443366600813

str_replace在约0.00001秒时快速放置。这种差异在许多调用

时会很明显