Я пытаюсь передать 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: Извините, если я пропустил какие-либо фигурные скобки. Я вводил вручную в зависимости от моих исходных данных
Обратите внимание, что Ваш вопрос может быть вне темы здесь, но это было забавное кодирование его. Так как Вы отправили вопрос на 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