【问题标题】:Converting a SimpleXML Object to an Array [closed]将 SimpleXML 对象转换为数组 [关闭]
【发布时间】:2011-09-04 06:25:31
【问题描述】:

我遇到了将 SimpleXML 对象转换为数组的函数here

/**
 * 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;
}

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

我知道 SimpleXML 对象与数组足够接近,因为它利用 PHP 中的 ArrayAccess 接口,但它仍然不能很好地用作具有多维数组的数组,即循环。

感谢大家的帮助

【问题讨论】:

  • 这是什么原因?是循环的吗?因为在这种情况下,您应该能够毫无问题地循环 SimpleXMLElement 对象的各个部分。例如,如果您使用 SimpleXML 解析 ATOM 提要,您可以执行以下操作:foreach($xml-&gt;entry as $entry),然后访问 $entry-&gt;title 等。从循环内。
  • 请注意,将(array) 添加到上面(即@json_decode(@json_encode((array)$simple_xml_object ), 1);),如PHP 手册后面的注释中所述,可能会导致Node no longer exists 错误。
  • 这个问题是关于什么的? json_encode 对 simplexml 元素进行树遍历。你有什么不同的期望?你如何定义“有点hacky”?在您看来,这种方法有什么不可靠的地方?什么不高效?
  • 这个问题我很清楚,所以我建议重新打开它。

标签: php xml arrays


【解决方案1】:

我在PHP manual comments

/**
 * 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。

【讨论】:

  • 请注意,这不会将多维对象转换为纯数组,即子元素仍然是SimpleXMLElements。这是因为is_object($node) 为子对象返回false,即第二次递归内的gettype($node)"array"。更合适的方法是the comment just below it。与第一个(原始)方法和 json 方法相比,第二种方法会带来一些性能影响:codepad.viper-7.com/eHhSNR,这使得 json 方法在性能方面再次可用
  • @Arjan:您错过了对版权所有者和作者的正确归属。出于方便的原因,我还添加了一些许可文档块标签。当您从网站上的 PHP 手册中复制代码示例时,请小心。它们与许可证兼容,但需要归属。由于 CC 不是专门为软件设计的,因此代码示例很可能无法在现实生活中使用,它们只是用于展示/解释某些东西。如果您不归属和隐藏版权所有者,这通常会丢失。
  • 这个函数不能递归工作。这是一个更好的版本:stackoverflow.com/questions/2726487/…
  • 是否可以将 Object 转换为 XML? @Arjan
  • 正如@HalilÖzgür 所说,它不会转换SimpleXMLElements 的数组。虽然可以使用$out[$index] = is_object($node) || is_array($node) ? xml2array($node) : $element; 修复它所以即使它是一个数组也会更深入
【解决方案2】:

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

...

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

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

【讨论】:

  • 这种方法会丢失 CDATA 内容。使用 PHP 5.5.21 测试
  • 您不必使用json_**code。只需使用(object) (array) $xml 即可完成! ;-)
  • @MonkeyMonk 仅当 XML 具有“扁平”结构时才适用。警告!使用json_** 获取数组将根据子对象的数量(一个与多个)产生不同的结果。
  • @jmarceli 好点,很高兴知道! ;-) 泰!
  • 是的,正如上面所指出的,不需要 json 编码/解码 $data = (array)simplexml_load_string($xml);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-05
  • 2020-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多