我有以下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秒时快速放置。这种差异在许多调用