Создайте модель Json для вызова API Xml2Json

#json #xml #flutter #api #dart

#json #xml #трепетать #API #дротик

Вопрос:

Я вызываю Api, который возвращает данные в XMl

Затем я преобразую его из XML в Json использование Xml2Json , чтобы затем декодировать и получить a JsonMap , что хорошо возвращает карту.

Когда я затем перейду к do locations.fromJson , чтобы иметь возможность вызывать данные из моей модели, это возвращается как null .

Я предполагаю, что преобразование из XML может усложниться, но я перепробовал все возможности, проанализировав весь ответ, раздел, который мне нужен, и изменив модель всеми возможными способами.

Данные возвращаются нормально , как Json , но при их анализе с помощью моей модели возникает некоторое несоответствие, сделанное с помощью quicktype.io

Когда я вызываю его каким-либо образом, будь то print поиск данных или извлечение данных, он возвращается в null vehicleActivity

Этот звонок

 Futurelt;Locationsgt; fetchLiveLocations() async {  var client = http.Client();  var locations;  Xml2Json xml2Json = new Xml2Json();      try{  var response = await client.get(  'https_call');   if (response.statusCode == 200) {  xml2Json.parse(response.body);  var jsonString = xml2Json.toGData();  var jsonMap = json.decode(jsonString);  //jsonMap is returning fine   locations = Locations.fromJson(jsonMap);  //Returning as null   }  } catch(Exception) {  return locations;  }   return locations;  }   

Верхняя часть модели Json

 import 'dart:convert';  Locations locationsFromJson(String str) =gt; Locations.fromJson(json.decode(str));  String locationsToJson(Locations data) =gt; json.encode(data.toJson());  class Locations {  Locations({  this.vehicleActivity,  });   Listlt;VehicleActivitygt; vehicleActivity;   factory Locations.fromJson(Maplt;String, dynamicgt; json) =gt; Locations(  vehicleActivity: Listlt;VehicleActivitygt;.from(json["VehicleActivity"].map((x) =gt; VehicleActivity.fromJson(x))),  );   Maplt;String, dynamicgt; toJson() =gt; {  "VehicleActivity": Listlt;dynamicgt;.from(vehicleActivity.map((x) =gt; x.toJson())),  }; }  class VehicleActivity {  VehicleActivity({  this.recordedAtTime,  this.itemIdentifier,  this.validUntilTime,  this.monitoredVehicleJourney,  this.extensions,  });   DateTime recordedAtTime;  String itemIdentifier;  DateTime validUntilTime;  MonitoredVehicleJourney monitoredVehicleJourney;  Extensions extensions;   factory VehicleActivity.fromJson(Maplt;String, dynamicgt; json) =gt; VehicleActivity(  recordedAtTime: DateTime.parse(json["RecordedAtTime"]),  itemIdentifier: json["ItemIdentifier"],  validUntilTime: DateTime.parse(json["ValidUntilTime"]),  monitoredVehicleJourney: MonitoredVehicleJourney.fromJson(json["MonitoredVehicleJourney"]),  extensions: Extensions.fromJson(json["Extensions"]),  );  

Возвращенный XML-файл

 lt;Siri xmlns="http://www.siri.org.uk/siri" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.siri.org.uk/siri http://www.siri.org.uk/schema/2.0/xsd/siri.xsd" version="2.0"gt; lt;ServiceDeliverygt; lt;ResponseTimestampgt;2021-12-03T18:11:05.408806 00:00lt;/ResponseTimestampgt; lt;ProducerRefgt;ItoWorldlt;/ProducerRefgt; lt;VehicleMonitoringDeliverygt; lt;ResponseTimestampgt;2021-12-03T18:11:05.408806 00:00lt;/ResponseTimestampgt; lt;RequestMessageRefgt;5747b24flt;/RequestMessageRefgt; lt;ValidUntilgt;2021-12-03T18:16:05.408806 00:00lt;/ValidUntilgt; lt;ShortestPossibleCyclegt;PT5Slt;/ShortestPossibleCyclegt;  lt;VehicleActivitygt; lt;RecordedAtTimegt;2021-12-03T18:10:01 00:00lt;/RecordedAtTimegt; lt;ItemIdentifiergt;ad2c7031-ceac-4e7c-bc0c-9e667ad00dfelt;/ItemIdentifiergt; lt;ValidUntilTimegt;2021-12-03T18:16:05.408968lt;/ValidUntilTimegt; lt;MonitoredVehicleJourneygt; lt;LineRefgt;4lt;/LineRefgt; lt;DirectionRefgt;inboundlt;/DirectionRefgt; lt;FramedVehicleJourneyRefgt; lt;DataFrameRefgt;2021-12-03lt;/DataFrameRefgt; lt;DatedVehicleJourneyRefgt;4_20211203_18_04lt;/DatedVehicleJourneyRefgt; lt;/FramedVehicleJourneyRefgt; lt;PublishedLineNamegt;4lt;/PublishedLineNamegt; lt;OperatorRefgt;FTVAlt;/OperatorRefgt; lt;DestinationRefgt;03700324lt;/DestinationRefgt; lt;VehicleLocationgt; lt;Longitudegt;-0.719601lt;/Longitudegt; lt;Latitudegt;51.520305lt;/Latitudegt; lt;/VehicleLocationgt; lt;Bearinggt;30.0lt;/Bearinggt; lt;BlockRefgt;801312lt;/BlockRefgt; lt;VehicleRefgt;69921lt;/VehicleRefgt; lt;/MonitoredVehicleJourneygt; lt;Extensionsgt; lt;VehicleJourneygt; lt;Operationalgt; lt;TicketMachinegt; lt;TicketMachineServiceCodegt;B4lt;/TicketMachineServiceCodegt; lt;JourneyCodegt;1815lt;/JourneyCodegt; lt;/TicketMachinegt; lt;/Operationalgt; lt;VehicleUniqueIdgt;69921lt;/VehicleUniqueIdgt; lt;DriverRefgt;801312lt;/DriverRefgt; lt;/VehicleJourneygt; lt;/Extensionsgt; lt;/VehicleActivitygt;  

Комментарии:

1. Во — первых, кажется проще просто использовать возможности xml пакета для анализа XML непосредственно в любые классы (или более простые карты и списки), которые вам нужны, вместо того, чтобы использовать JSON. Вы уверены, что не создаете исключение и не попадаете в катетер, который просто возвращает значение null? Добавьте print заявления.

2. @RichardHeap Спасибо за ваш ответ. Во-первых, я думаю, что я тоже пришел к этому выводу, чтобы держать его в Xml себе . Во — вторых, я использовал Print операторы, и это выбрасывает null @ vehicleActivity . То, что я хочу извлечь, — это Lat,Long для каждого примера в списке

3. добавьте фрагмент XML — файла

4. @RichardHeap Извиняюсь, думал, я включил один — вставил один сейчас. Есть Siri текст префикса, а затем xml данные находятся в дереве lt;/VehicleActivitygt; , чтобы lt;/VehicleActivitygt;

Ответ №1:

Вот пример VehicleActivity класса — обратите внимание, что он не обрабатывает никаких ошибок, таких как пропущенные теги XML или неразрешимые даты, которые вы должны добавить самостоятельно.

 class VehicleActivity {  VehicleActivity({  this.recordedAtTime,  this.itemIdentifier,  this.validUntilTime,  });   DateTime? recordedAtTime;  String? itemIdentifier;  DateTime? validUntilTime;   factory VehicleActivity.fromElement(XmlElement vaElement) =gt; VehicleActivity(  recordedAtTime: DateTime.parse(  vaElement.findElements('RecordedAtTime').first.text,  ),  itemIdentifier: vaElement.findElements('ItemIdentifier').first.text,  validUntilTime: DateTime.parse(  vaElement.findElements('ValidUntilTime').first.text,  ),  ); }  

Вы бы использовали заводской метод из заключающего тега (аналогично тому, как пишутся ваши парсеры JSON) для каждого из найденных им тегов активности транспортного средства. (Обратите внимание, что XML может иметь несколько тегов с одинаковыми именами, поэтому код используется first для поиска (надеюсь) одного и того же тега. Если вы хотите правильно проанализировать XML, вам нужно разобраться с этим — и обратите внимание, что переход через JSON может нарушить это, — но не с вашей простой схемой.)

Вот простой пример, который просто находит все теги активности транспортного средства:

 final doc = XmlDocument.parse(utf8.decode(response.bodyBytes));  final allActivities = doc  .findAllElements('VehicleActivity')  .map((e) =gt; VehicleActivity.fromElement(e))  .toList();  print(allActivities);  

Комментарии:

1. Спасибо за ваш ответ. Первый вопрос: где находится класс модели? Должен ли я хранить его в отдельном .dart файле, как моя модель Json? И 2, как пересмотренный xml вызов вписывается в мой Https-вызов, размещаю ли я его сразу после вызова в fetch методе, где xml2json находится синтаксический анализ?

2. Как вы структурируете свой код, зависит от вас, но имеет смысл разделять классы моделей. Да, замените чтение файла на response.body или utf8.decode(response.bodyBytes) — я обновил ответ, чтобы показать это.