SimpleXML Attributes to Array

前端 未结 5 946
臣服心动
臣服心动 2020-12-15 05:19

Is there any more elegant way to escape SimpleXML attributes to an array?

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


        
相关标签:
5条回答
  • 2020-12-15 05:30

    You could convert the whole xml document into an array:

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

    For more information see: https://github.com/gaarf/XML-string-to-PHP-array

    0 讨论(0)
  • 2020-12-15 05:35

    I think you will have to loop through. You can get it into array once you read 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') ....
    }
    
    0 讨论(0)
  • 2020-12-15 05:44

    Don't directly read the '@attributes' property, that's for internal use. Anyway, attributes() can already be used as an array without needing to "convert" to a real array.

    For example:

    <?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"
    

    If you want it to be a "true" array, you're gonna have to loop:

    $attrArray = array();
    $attr = $x->test[0]->a[0]->attributes();
    
    foreach($attr as $key=>$val){
        $attrArray[(string)$key] = (string)$val;
    }
    
    0 讨论(0)
  • 2020-12-15 05:45

    For me below method worked

    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)
        ];
    }
    

    This also provides me all the attributes as well, which I didn't get from any other method.

    0 讨论(0)
  • 2020-12-15 05:48

    a more elegant way; it gives you the same results without using $attributes[ '@attributes' ] :

    $attributes = current($element->attributes());
    
    0 讨论(0)
提交回复
热议问题