JSON к преобразователю CSV, где JSON имеет непоследовательные столбцы в массиве

Я пытаюсь передать JSON файлу CSV, где столбцы JSON в массивах не последовательны. См. ниже демонстрационные данные JSON, которые я пытаюсь преобразовать.

Обновленный JSON

{  
   "data":[  
      {  
         "country_id":"001",
         "countryinfolist":{  
            "Elements":[  
               {  
                  "NAme":"country",
                  "Value":"USA"
               },
               {  
                  "Name":"capital",
                  "Value":"DC"
               },
               {  
                  "Name":"Largest City",
                  "Value":"NYC"
               }
            ]
         },
         "Demolist":{  
            "Demoid":[  
               {  
                  "value":"100000",
                  "name":"POPOLATION"
               },
               {  
                  "value":"6000000",
                  "name":"GDP"
               },
               {  
                  "value":"ENGLISH",
                  "name":"Plang"
               },
               {  
                  "value":"SPANISH",
                  "name":"Slang"
               }
            ]
         }
      },
      {  
         "country_id":"002",
         "countryinfolist":{  
            "Elements":[  
               {  
                  "NAme":"country",
                  "Value":"Mexico"
               },
               {  
                  "Name":"Largest City",
                  "Value":"Mexico City"
               },
               {  
                  "NAme":"Currency",
                  "Value":"Peso"
               }
            ]
         },
         "Demolist":{  
            "Demoid":[  
               {  
                  "value":"50000",
                  "name":"POPOLATION"
               },
               {  
                  "value":"SPANISH",
                  "name":"Plang"
               },
               {  
                  "value":"Soccer",
                  "name":"Sports"
               }
            ]
         }
      }
   ]
}

Поскольку Вы видите, что массив имеет другое число столбцов. Я хочу выйти помещенный как ниже

Country_id,country,capital, POPOLATION ,Sports
001,USA,DC,100000,null
002,MEXICO,null,50000,Soccer

PS: Извините, если я пропустил какие-либо фигурные скобки. Я вводил вручную в зависимости от моих исходных данных

0
задан 14 December 2019 в 00:29

1 ответ

Обратите внимание, что Ваш вопрос может быть вне темы здесь, но это было забавное кодирование его. Так как Вы отправили вопрос на Ubuntu SE, я полагаю, что Вы думали о кодировании его в ударе - но удар не является действительно никакой забавой когда дело доходит до JSON и нулевых значений. Это - результат работы примерно 20 минут в PHP. Это - командная строка PHP, таким образом, никакая потребность в веб-сервере.

<?php
const CSVSeparator = ',';
$json = json_decode(file_get_contents($argv[1]), true);
$csvfields = array('Country_id', 'country', 'capital', 'POPOLATION' /* sic! */, 'Sports');
$csvfields_lower = array();
$sep = '';
foreach ($csvfields as $csvfield) {
    $csvfields_lower[] = mb_strtolower($csvfield);
    echo $sep . $csvfield;
    $sep = CSVSeparator;
}
echo PHP_EOL;
foreach ($json['data'] as &$countrydata) {
    $data = array_fill_keys($csvfields_lower, null);
    $data['country_id'] = $countrydata['country_id'];
    foreach (array('countryinfolist' => 'Elements', 'Demolist' => 'Demoid') as $list => &$elements) {
        foreach ($countrydata[$list][$elements] as &$countryelement) {
            $datakey = null; $datavalue = null;
            foreach ($countryelement as $rawkey => $rawvalue) {
                $key = mb_strtolower($rawkey);
                switch ($key) {
                    case 'name':
                        $value = mb_strtolower($rawvalue);
                        if (array_key_exists($value, $data)) $datakey = $value;
                        break;
                    case 'value':
                        $datavalue = $rawvalue;
                        break;
                }
            }
            if ($datakey !== null) $data[$datakey] = $datavalue;
        }
    }
    unset($elements);
    $sep = '';
    foreach ($data as $key => $value) {
        echo $sep . ($value === null ? 'null' : $value);
        $sep = CSVSeparator;
    }
    echo PHP_EOL;
}
unset($countrydata);

Это не игравший в гольф код, а скорее предназначенный для хорошей удобочитаемости. Это предполагает, что cписок полей исправлен (country_id, country и так далее). (Можно отметить, что корректное написание поп ulation, следовательно я отметил так! в cписке полей.).

, Как это работает?

Это загружает файл, данный как первый параметр командной строки, декодирует содержание JSON в ассоциативный массив и выполняет итерации по этому массиву. Все ключи преобразовываются в нижний регистр для предотвращения противных вещей как Name, name и NAme. Данные устанавливаются в NULL заранее с командой array_fill_keys. Любые данные, которые остаются пустыми до вывода, производятся как строка null.

Протест: поле $data предварительно загружено с [1 110] значения. Я сделал это, потому что это выглядит более эстетичным. Конечно, также было бы возможно установить их на строки, содержащие Word null. В этом случае выходной цикл мог быть заменен простым implode.

Запущенный программа для командной строки как это:

php json2csv.php data1.json
0
ответ дан 21 December 2019 в 23:34

Другие вопросы по тегам:

Похожие вопросы: