Извлечение данных из сложного JSON во Flutter

Я работаю над извлечением данных из более сложного JSON с неизвестной структурой, его структура меняется в процессе работы, Ссылка на образец JSON: http://afs-i.com/json.json

Пожалуйста, найдите мой код здесь: http://afs-i.com/main.dart

заранее спасибо

Обновлять: Я извлек данные с помощью кода PHP, вы можете найти результат здесь: http://afs-i.com/json.php

Пожалуйста, это мой PHP-код:

$arraycars=array();
$y=json_decode($x);
//  echo "<pre>";
//  var_dump($y->tree[0]->children); 
foreach ($y->tree[0]->children as $f) {
  if (isset($f->vid)){
       global $arraycars;
       $arraycars[]=$f;
   } elseif (isset($f->children)){
     if (sizeof($f->children) > 0){
        coolectcars($f->children);
     }
    }   
   }
   function coolectcars($array){
   // var_dump($array);
   foreach ($array as $f) {
     if (isset($f->vid)){
        global $arraycars;
        $arraycars[]=$f;
     } elseif (isset($f->children)){
        if (sizeof($f->children) > 0){
            coolectcars($f->children);
        }
     }  
   }
  }
  echo json_encode($arraycars);

Обновление: 2 У меня проблема с нулевой ошибкой для этого кода: Ошибка:

I/flutter ( 4264): NoSuchMethodError: The method 'forEach' was called on 
 null.
I/flutter ( 4264): Receiver: null
I/flutter ( 4264): Tried calling: forEach(Closure: (Children) => Null)

Код:

List<Children> cars = [];
Queue numQ = new Queue();
numQ.addAll(parsed["tree"][0]["children"]);
Iterator i = numQ.iterator;

while (i.moveNext()) {
//    print("ddddddd ${i.current}");
 if (i.current.containsKey("vid")) {
  cars.add(new Children(
      i.current['vid'], i.current['protocol'], i.current['datetime'],
      i.current['gpss']));
  } else {
  Queue numQ = new Queue();
  if (i.current["children"] != null) {
    numQ.addAll(i.current["children"]);
  //        iterate(numQ);
    List<Children> carse=[];
     carse = iterate(numQ);
     carse.forEach((data){
       cars.add(data);
     }) ;

   }
  }
 }
 cars.forEach((data) {
  print(data.toString());
 });
 List<Children> iterate(Queue numQ) {
 List<Children> cars=new List<Children>();
 Iterator i = numQ.iterator;
 while (i.moveNext()) {
 print("ddddddd ${i.current}");
 if (i.current.containsKey("vid")) {
  cars.add(new Children(
      i.current['vid'], i.current['protocol'], i.current['datetime'],
      i.current['gpss']));
  } else {
  if (i.current["children"] != null) {
    Queue numQ = new Queue();
    numQ.addAll(i.current["children"]);
    List<Children> carse=[];
    carse = iterate(numQ);
    carse.forEach((data){
      cars.add(data);
    }) ;
  }
  }
 return cars;
 } 
 }
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
0
2 038
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

вставьте этот import 'dart:convert'; в файл вашего виджета вверху.

скажем, у вас есть json в

var response

тогда

var jsonDecoded= json.decode(response);

теперь вы можете получить имя и user_id следующим образом:

var user_id= jsonDecoded["tree"][0]["user_id"];

var name = jsonDecoded["tree"][0]["name"];

ПРИМЕЧАНИЕ. Я получаю эти значения из первого объекта (индекс 0). Если вам нужны значения для каждого объекта, вы можете выполнить цикл, чтобы получить его.

не та же структура для цикла с ним, мне нужно в цикле (jsonDecoded ["tree"] [0] ["children"])

Eslam saad 23.10.2018 12:35

и это массив (объект (который мне нужен) и иногда с новым массивом дерева) m.

Eslam saad 23.10.2018 12:37

привет, как можно проверить, существует ли значение. Как PHP if (isset ($ name ['tree'])) {...}

Márcio Rossato 20.10.2020 16:58

Хорошее место для конвертации JSON в dart здесь

шляпы к Reddit url

просто скопируйте свой json в текстовое поле и сгенерируйте, он автоматически сгенерируется для вас.

При этом вы можете вызвать fromJson и передать ему json, затем вы также можете получить для него автоматическое завершение.

например: использование

final response =
        await http.get('http://afs-i.com/json.json');

if (response.statusCode == 200) {
   final Autogenerated respJson = Autogenerated.fromJson(json.decode(response.body));
   print(respJson.tree[0].userId);
}

Хороший. Я вижу, что это поможет, но конвертер дает мне несколько классов, как передать мой json в первый класс (автоматически сгенерированный) и получить список дочерних объектов.

Eslam saad 23.10.2018 11:01

fromJSON принимает в качестве аргумента Map <String, dynamic>, если я не ошибаюсь, когда вы получаете ответ, вы можете просто передать ответ этой функции.

yuzuriha 23.10.2018 11:41

Можете ли вы проверить обновления в посте, это то, что мне нужно

Eslam saad 23.10.2018 12:33

Я предпочитаю использовать built_value для десериализации / сериализации json. Это более элегантно. Самостоятельно записывать fromJson не нужно. built_value сгенерирует для вас десериализаторы / сериализаторы. Вы можете проверить статьи github или это и это на built_value.

из-за сложности мне пришлось выполнять итерацию в json с настраиваемой итерацией. Я использовал Queue, но у меня проблема с нулевыми объектами

Eslam saad 24.10.2018 20:37

вы можете найти обновление: 2 в сообщении, теперь проблема только с нулями

Eslam saad 24.10.2018 20:43
Ответ принят как подходящий

Окончательный ответ, который я получил:

final parsed = json.decode(response.body);
List<Children> cars = [];
Queue numQ = new Queue();
numQ.addAll(parsed["tree"][0]["children"]);
Iterator i = numQ.iterator;

while (i.moveNext()) {
  if (i.current.containsKey("vid")) {

    cars.add(new Children(
        i.current['vid'],
        i.current['datetime'],
       ));

} else {
  Queue numQ = new Queue();
  if (i.current["children"].toString() != "[]") {
    numQ.addAll(i.current["children"]);
    List<Children> carse = [];
    carse = iterate(numQ);
    carse.forEach((data) {
      cars.add(data);
    });
  }
}
}


List<Children> iterate(Queue numQ) {
List<Children> cars = new List<Children>();
Iterator i = numQ.iterator;
while (i.moveNext()) {
if (i.current.containsKey("vid")) {
  if (i.current.containsKey("vid")) {

    cars.add(new Children(
        i.current['vid'],
        i.current['datetime'],
       ));

}
 } else {
  if (i.current["children"].toString() != "[]") {
  Queue numQ = new Queue();
  if (i.current["children"].toString() != "[]") {
    numQ.addAll(i.current["children"]);
    List<Children> carse = [];
    carse = iterate(numQ);
    carse.forEach((data) {
      cars.add(data);
    });
  }
  }
}
 return cars;
 }

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