【问题标题】:SimpleXML Attributes to ArraySimpleXML 属性到数组
【发布时间】:2012-07-11 11:52:16
【问题描述】:

有没有更优雅的方式将 SimpleXML 属性转义到数组中?

$result = $xml->xpath( $xpath );
$element = $result[ 0 ];
$attributes = (array) $element->attributes();
$attributes = $attributes[ '@attributes' ];

我真的不想为了提取键/值对而循环遍历它。我所需要的就是将它放入一个数组中,然后将其传递。我原以为attributes() 默认会这样做,或者至少可以选择。但是我什至无法在任何地方找到上述解决方案,我必须自己弄清楚。我是不是把这件事复杂化了?

编辑:

在确定访问@attributes 数组是否安全之前,我仍在使用上述脚本。

【问题讨论】:

    标签: php arrays attributes simplexml


    【解决方案1】:

    对我来说,以下方法有效

    function xmlToArray(SimpleXMLElement $xml)
    {
        $parser = function (SimpleXMLElement $xml, array $collection = []) use (&$parser) {
            $nodes = $xml->children();
            $attributes = $xml->attributes();
    
            if (0 !== count($attributes)) {
                foreach ($attributes as $attrName => $attrValue) {
                    $collection['@attributes'][$attrName] = strval($attrValue);
                }
            }
    
            if (0 === $nodes->count()) {
                if($xml->attributes())
                {
                    $collection['value'] = strval($xml);
                }
                else
                {
                    $collection = strval($xml);
                }
                return $collection;
            }
    
            foreach ($nodes as $nodeName => $nodeValue) {
                if (count($nodeValue->xpath('../' . $nodeName)) < 2) {
                    $collection[$nodeName] = $parser($nodeValue);
                    continue;
                }
    
                $collection[$nodeName][] = $parser($nodeValue);
            }
    
            return $collection;
        };
    
        return [
            $xml->getName() => $parser($xml)
        ];
    }
    

    这也为我提供了所有其他方法都没有的属性。

    【讨论】:

      【解决方案2】:

      您可以将整个 xml 文档转换为数组:

      $array = json_decode(json_encode((array) simplexml_load_string("<response>{$xml}</response>")), true);
      

      欲了解更多信息,请参阅:https://github.com/gaarf/XML-string-to-PHP-array

      【讨论】:

        【解决方案3】:

        更优雅的方式;它在不使用 $attributes[ '@attributes' ] 的情况下为您提供相同的结果:

        $attributes = current($element->attributes());
        

        【讨论】:

        • 绝对简单,紧凑,操作更少。
        • 这应该是答案
        【解决方案4】:

        我认为您将不得不循环。读取 xml 后即可将其放入数组中。

        <?php
        function objectsIntoArray($arrObjData, $arrSkipIndices = array())
        {
        $arrData = array();
        
        // if input is object, convert into array
        if (is_object($arrObjData)) {
            $arrObjData = get_object_vars($arrObjData);
        }
        
        if (is_array($arrObjData)) {
            foreach ($arrObjData as $index => $value) {
                if (is_object($value) || is_array($value)) {
                    $value = objectsIntoArray($value, $arrSkipIndices); // recursive call
                }
                if (in_array($index, $arrSkipIndices)) {
                    continue;
                }
                $arrData[$index] = $value;
            }
        }
        return $arrData;
        }
        
        $xmlStr = file_get_contents($xml_file);
        $xmlObj = simplexml_load_string($xmlStr);
        $arrXml = objectsIntoArray($xmlObj);
        
        foreach($arrXml as $attr)
          foreach($attr as $key->$val){
         if($key == '@attributes') ....
        }
        

        【讨论】:

        • 什么是objectsIntoArray?另外,您不应该直接阅读'@attributes',这就是-&gt;attributes() 的用途。
        • 对不起,我从我的代码中粘贴了缺少顶部的部分,只是编辑了它。
        【解决方案5】:

        不要直接读取'@attributes' 属性,这是供内部使用的。无论如何,attributes() 已经可以用作数组,而无需“转换”为真正的数组。

        例如:

        <?php
        $xml = '<xml><test><a a="b" r="x" q="v" /></test><b/></xml>';
        $x = new SimpleXMLElement($xml);
        
        $attr = $x->test[0]->a[0]->attributes();
        echo $attr['a']; // "b"
        

        如果你想让它成为一个“真正的”数组,你将不得不循环:

        $attrArray = array();
        $attr = $x->test[0]->a[0]->attributes();
        
        foreach($attr as $key=>$val){
            $attrArray[(string)$key] = (string)$val;
        }
        

        【讨论】:

        • 是的,但问题是它仍然认为自己是一个 SimpleXML 元素,因此您必须将$attr[ 'a' ] 类型转换为字符串才能正常工作。我将这个数组传递给另一个不知道它应该是什么类型的类,只知道它需要是一个数组。
        • 啊,你在编辑中得到它......循环是否比我目前正在做的“更好”?我认为这样做没有循环会更快。
        • @showerhead:我不知道是不是更好,但我一直学会不要直接读取'@attributes'属性。
        • @showerhead:也许我错了,我不确定我从哪里得到的。如果它适合你,我说使用它。文档根本没有提到'@attributes',既不使用也不使用。
        • 我会留意的。假设没有其他答案出现,我今晚晚些时候会接受这个。虽然我想我会对这两种解决方案进行一些性能测试,看看哪一种效果更好。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-23
        • 1970-01-01
        相关资源
        最近更新 更多