将SimpleXML对象转换为数组


74

我碰到SimpleXML对象转换为阵列的这种功能在这里

/**
 * function object2array - A simpler way to transform the result into an array 
 *   (requires json module).
 *
 * This function is part of the PHP manual.
 *
 * The PHP manual text and comments are covered by the Creative Commons 
 * Attribution 3.0 License, copyright (c) the PHP Documentation Group
 *
 * @author  Diego Araos, diego at klapmedia dot com
 * @date    2011-02-05 04:57 UTC
 * @link    http://www.php.net/manual/en/function.simplexml-load-string.php#102277
 * @license http://www.php.net/license/index.php#doc-lic
 * @license http://creativecommons.org/licenses/by/3.0/
 * @license CC-BY-3.0 <http://spdx.org/licenses/CC-BY-3.0>
 */
function object2array($object)
{
    return json_decode(json_encode($object), TRUE); 
}

因此,我对XML字符串的采用类似于:

function xmlstring2array($string)
{
    $xml   = simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA);

    $array = json_decode(json_encode($xml), TRUE);

    return $array;
}

它工作得很好,但似乎有点黑吗?有没有更有效/更强大的方法来做到这一点?

我知道SimpleXML对象与数组足够接近,因为它利用了PHP中的ArrayAccess接口,但是与多维数组(即循环)一起使用时,仍然不能很好地工作。

谢谢大家的帮助


2
是什么原因呢?循环吗?因为在那种情况下,您应该能够循环SimpleXMLElement对象的某些部分而不会出现任何问题。例如,如果您要使用SimpleXML解析ATOM提要,则可以执行以下操作:foreach($xml->entry as $entry)然后访问$entry->titleet.c。从循环内。
Karl Laurentius Roos

1
请注意,如PHP手册后面的注释中所述(array),在上述内容(即@json_decode(@json_encode((array)$simple_xml_object ), 1);)上添加可能会导致Node no longer exists错误。
HalilÖzgür13年

这个问题是关于什么的?json_encode对simplexml元素进行树遍历。您有什么不同的期望?您如何定义“有点怪异”?在您眼中,这种方法有什么不足之处?什么效率不高?
2013年

2
这个问题对我来说很清楚,因此我建议重新打开它。
Dan Nissenbaum 2014年

Answers:


90

我在PHP手册注释中找到了这个:

/**
 * function xml2array
 *
 * This function is part of the PHP manual.
 *
 * The PHP manual text and comments are covered by the Creative Commons 
 * Attribution 3.0 License, copyright (c) the PHP Documentation Group
 *
 * @author  k dot antczak at livedata dot pl
 * @date    2011-04-22 06:08 UTC
 * @link    http://www.php.net/manual/en/ref.simplexml.php#103617
 * @license http://www.php.net/license/index.php#doc-lic
 * @license http://creativecommons.org/licenses/by/3.0/
 * @license CC-BY-3.0 <http://spdx.org/licenses/CC-BY-3.0>
 */
function xml2array ( $xmlObject, $out = array () )
{
    foreach ( (array) $xmlObject as $index => $node )
        $out[$index] = ( is_object ( $node ) ) ? xml2array ( $node ) : $node;

    return $out;
}

它可以帮助您。但是,如果将XML转换为数组,则会丢失可能存在的所有属性,因此无法返回到XML并获得相同的XML。


14
请注意,这不会将多维对象转换为纯数组,即子元素仍然SimpleXMLElement是s。这是因为子对象的is_object($node)返回false值,即gettype($node)第二个递归内部是"array"。一种更合适的方法是在它下面的注释。与第一个(原始)方法和json方法相比,第二个方法具有一些性能影响:codepad.viper-7.com/eHhSNR,这使json方法在性能上再次可用
HalilÖzgür13年

1
@Arjan:您错过了对版权所有者和作者的适当归因。为了方便起见,我还添加了一些许可文档块标签。当您从网站上的PHP手册中复制代码示例时,请多加注意。它们与许可证兼容,但是需要注明出处。由于CC不是专门为软件设计的,因此代码示例很可能在现实生活中不可用,它们仅可用于显示/解释某些内容。如果您不归因并隐藏版权所有者,那么这常常会丢失。
hakre

2
此函数不能递归工作。这里是一个更好的版本:stackoverflow.com/questions/2726487/...
博彭宁斯

可以将对象转换为XML吗?@Arjan
宝石

正如@HalilÖzgür所说,它不会转换SimpleXMLElements数组。尽管可以使用它进行修复, $out[$index] = is_object($node) || is_array($node) ? xml2array($node) : $element;所以即使它是一个数组,它也会更深入
Javier S

67

(array)在simplexml对象之前的代码中缺少Just :

...

$xml   = simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA);

$array = json_decode(json_encode((array)$xml), TRUE);
                                 ^^^^^^^
...

3
这种方法缺少CDATA内容。使用PHP 5.5.21测试
Wouter

4
您不必使用json_**code。只需使用即可(object) (array) $xml完成!;-)
猴子和尚

9
@MonkeyMonk只有在XML具有“扁平”结构的情况下才是正确的。警告!使用json_**用于获取的阵列将根据子对象(一个VS多个)的数产生不同的结果。
jmarceli 2015年

@jmarceli好一点,很高兴知道!;-) Ty!
僧侣

是的,不需要像上面$ data =(array)simplexml_load_string($ xml)所指出的那样进行json编码/解码。
TURTLE '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.