简体   繁体   中英

PHP: recursively convert array to string if key has a certain value

I've got some XML inputs that I convert to PHP arrays using LaLit's XML2Array .

$array = XML2Array::createArray($xml);

This gives me a multidimensionnal array like this one for instance:

Array (
    [title] =>      Array ( 
                        [@cdata] => My Playlist 
                    ) 
    [tracks] =>     Array (
                        [track] => Array (
                            [date] =>       2019-10-15T09:41:21+0000 
                            [position] =>   4
                            [title] =>      Array ( 
                                                [@cdata] => Hello 
                                            ) 
                            [creator] =>    Array ( 
                                                [@cdata] => The Beatles
                                            ) 
                        )
                        [track] => Array (
                            [date] =>       2019-10-15T09:41:21+0000 
                            [position] =>   5
                            [title] =>      Array ( 
                                                [@cdata] => How High? 
                                            ) 
                            [creator] =>    Array ( 
                                                [@cdata] => Olivier Boogie 
                                            ) 
                        )
                    )
)

Some values are formatted like this:

Array ( [@cdata] => value )

I would like to run a recursive function on $array that would "flatten" @cdata arrays, to get this result instead:

Array (
    [title] =>      My Playlist
    [tracks] =>     Array (
                        [track] => Array (
                            [date] =>       2019-10-15T09:41:21+0000 
                            [position] =>   4
                            [title] =>      Hello
                            [creator] =>    The Beatles
                        )
                        [track] => Array (
                            [date] =>       2019-10-15T09:41:21+0000 
                            [position] =>   5
                            [title] =>      How High?
                            [creator] =>    Olivier Boogie
                        )
                    )
)

How could I do? Thanks !

Here is a basic recursive version if you were interested.

<?php

$cloned_data = $data;

function flattenCData($data,&$cloned_data){
    foreach($data as $key => $value){
        if(is_array($value)){
            if(isset($value['@cdata'])) $cloned_data[$key] = $value['@cdata'];
            else flattenCData($value,$cloned_data[$key]);
        }
    }
}

flattenCData($data,$cloned_data);
print_r($cloned_data);

Demo: https://3v4l.org/7s0sU

Just clone the current array to avoid concurrent modification along with iteration issue when moving recursively. Use & to make sure that you edit the same second cloned array. Rest is intuitive.

You can use array_walk to do so.

function flatten_cdata($array) {
  array_walk($array, function (&$item, $key) {
    if (!is_array($item)) {
      return;
    }
    if (isset($item['@cdata'])) {
      $item = $item['@cdata'];
      return;
    }
    $item = flatten_cdata($item);
  });
  return $array;
}

var_dump(flatten_cdata([
    'track' => [
        'date' => '2019-10-15T09:41:21+0000',
        'position' => 5,
        'title' => [
            '@cdata' => 'How High?',
        ],
        'creator' => [
            '@cdata' => 'Olivier Boogie',
        ],
    ],
]));

Output:

Array
(
    [track] => Array
        (
            [date] => 2019-10-15T09:41:21+0000
            [position] => 5
            [title] => How High?
            [creator] => Olivier Boogie
        )

)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM