#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? Добавьте2. @RichardHeap Спасибо за ваш ответ. Во-первых, я думаю, что я тоже пришел к этому выводу, чтобы держать его в
Xml
себе . Во — вторых, я использовал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)
— я обновил ответ, чтобы показать это.