将SimpleXMLElement转换为PHP数组

32

变量$d来自于file_get_contents函数对一个URL的调用。

$answer = @new SimpleXMLElement($d);

以下是print_r($answer)的输出:

SimpleXMLElement Object
(
  [Amount] => 2698
  [Status] => OK
  [State] => FL
  [Country] => USA
)

我该如何获取每个元素的值并添加到数组中?我无法理解。

5个回答

64
在这种简单情况下,类型转换也将起作用:
$my_array = (array)$answer

12
这不是递归的。 - Jehong Ahn

56

这应该是有效的:

$xml = simplexml_load_string($xmlstring);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

1
我刚刚测试了一下,这个方法可行。它甚至可以递归使用,非常好。但是,如果出现非UTF-8字符,我会感到担忧。当json_encodejson_decode方法遇到非UTF-8字符时,它们往往会出错。尝试用try...catch包装可能是明智的,但我不知道是否有一种方法可以正确处理它(即编码为UTF-8)而不编写自定义解析器。 - Josh
3
json_encodehttp_build_query 都无法正确解析 <![CDATA[ ]]> 标记。两个函数都将其视为空对象,导致 http_build_query 完全忽略此标记。 - Shaun Cockerill

13
< p >变量$answer已经可以作为一个数组来使用。如果你希望将其放入一个真正的数组中,你可以这样做。

$array = array();
foreach($answer as $k => $v) {
  $array[$k] = $v;
}

1
我无法以以下方式迭代SimpleXMLElement对象 - Adam Baranyai

8

我对这个函数有些问题,因为将每个XML子元素强制转换为数组可能会在文本位于CDATA标记之间时出现问题。

我通过检查将子元素强制转换为数组的结果是否为空来解决了这个问题。如果是,那么将它强制转换为字符串,就可以得到正确的结果。

以下是我的修改版本,支持CDATA

function SimpleXML2ArrayWithCDATASupport($xml)
{   
    $array = (array)$xml;

    if (count($array) === 0) {
        return (string)$xml;
    }

    foreach ($array as $key => $value) {
        if (!is_object($value) || strpos(get_class($value), 'SimpleXML') === false) {
            continue;
        }
        $array[$key] = SimpleXML2ArrayWithCDATASupport($value);
    }

    return $array;
}

我发现json_encodehttp_build_query都有相同的症状,因此这种方法是最可靠的。 - Shaun Cockerill
1
它仍然忽略CDATA字段。我不得不使用$xml = simplexml_load_file('file.xml',SimpleXMLElement::class,LIBXML_NOCDATA);,但是然后您的函数就不再需要了,我可以只做json_decode(json_encode((array) $xml),true); - Rodrigo
遗憾的是,它仍然无法处理命名空间数据 :/ - Lukáš Klíma

1
这个函数将一个简单的XML递归解析为递归数组。
function SimpleXML2Array($xml){
    $array = (array)$xml;

    //recursive Parser
    foreach ($array as $key => $value){
        if(strpos(get_class($value),"SimpleXML")!==false){
            $array[$key] = SimpleXML2Array($value);
        }
    }

    return $array;
}

我对这个函数有问题,因为将每个XML子元素强制转换为数组可能会在文本位于CDATA标记之间时导致问题。 - Bo Pennings

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接