为 API 调用 Xml2Json 制作 Json 模型
Posted
技术标签:
【中文标题】为 API 调用 Xml2Json 制作 Json 模型【英文标题】:Make Json Model for API Call Xml2Json 【发布时间】:2022-01-10 00:56:58 【问题描述】:我正在调用一个在XMl
中返回数据的 API
然后我使用Xml2Json
将其从XML
转换为Json
,然后解码并获得JsonMap
,它可以很好地返回地图。
当我执行 locations.fromJson
以便能够从我的模型中调用数据时,返回为 null
。
我想从 XML 转换可能会很复杂,但我已经尝试了所有可能性,解析整个响应、我需要的部分并以所有可能的方式修改模型。
数据以Json
的形式返回正常,但在使用我的模型解析时,通过 quicktype.io 进行分析时出现了一些断开连接
当我以任何方式调用它时,无论是print
还是数据检索,它都会在 null
vehicleActivity
返回
电话
Future<Locations> 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) => Locations.fromJson(json.decode(str));
String locationsToJson(Locations data) => json.encode(data.toJson());
class Locations
Locations(
this.vehicleActivity,
);
List<VehicleActivity> vehicleActivity;
factory Locations.fromJson(Map<String, dynamic> json) => Locations(
vehicleActivity: List<VehicleActivity>.from(json["VehicleActivity"].map((x) => VehicleActivity.fromJson(x))),
);
Map<String, dynamic> toJson() =>
"VehicleActivity": List<dynamic>.from(vehicleActivity.map((x) => 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(Map<String, dynamic> json) => 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 文件
<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">
<ServiceDelivery>
<ResponseTimestamp>2021-12-03T18:11:05.408806+00:00</ResponseTimestamp>
<ProducerRef>ItoWorld</ProducerRef>
<VehicleMonitoringDelivery>
<ResponseTimestamp>2021-12-03T18:11:05.408806+00:00</ResponseTimestamp>
<RequestMessageRef>5747b24f</RequestMessageRef>
<ValidUntil>2021-12-03T18:16:05.408806+00:00</ValidUntil>
<ShortestPossibleCycle>PT5S</ShortestPossibleCycle>
<VehicleActivity>
<RecordedAtTime>2021-12-03T18:10:01+00:00</RecordedAtTime>
<ItemIdentifier>ad2c7031-ceac-4e7c-bc0c-9e667ad00dfe</ItemIdentifier>
<ValidUntilTime>2021-12-03T18:16:05.408968</ValidUntilTime>
<MonitoredVehicleJourney>
<LineRef>4</LineRef>
<DirectionRef>inbound</DirectionRef>
<FramedVehicleJourneyRef>
<DataFrameRef>2021-12-03</DataFrameRef>
<DatedVehicleJourneyRef>4_20211203_18_04</DatedVehicleJourneyRef>
</FramedVehicleJourneyRef>
<PublishedLineName>4</PublishedLineName>
<OperatorRef>FTVA</OperatorRef>
<DestinationRef>03700324</DestinationRef>
<VehicleLocation>
<Longitude>-0.719601</Longitude>
<Latitude>51.520305</Latitude>
</VehicleLocation>
<Bearing>30.0</Bearing>
<BlockRef>801312</BlockRef>
<VehicleRef>69921</VehicleRef>
</MonitoredVehicleJourney>
<Extensions>
<VehicleJourney>
<Operational>
<TicketMachine>
<TicketMachineServiceCode>B4</TicketMachineServiceCode>
<JourneyCode>1815</JourneyCode>
</TicketMachine>
</Operational>
<VehicleUniqueId>69921</VehicleUniqueId>
<DriverRef>801312</DriverRef>
</VehicleJourney>
</Extensions>
</VehicleActivity>
【问题讨论】:
首先,使用xml
包中的功能将 XML 直接解析为您需要的任何类(或更简单的映射和列表)似乎更容易 - 而不是通过 JSON。你确定你没有抛出异常并落入只返回空值的cath吗?添加print
语句。
@RichardHeap 感谢您的回复。首先,我想我也得出了这个结论,将其保留在Xml
中。其次,我一直在使用Print
语句,它正在抛出null
@vehicleActivity
。我要提取的是列表中每个示例的Lat,Long
添加XML文件的sn-p
@RichardHeap 抱歉,我以为我已经包含了一个 - 现在已经插入了一个。有Siri
前缀文本,然后xml
数据在树</VehicleActivity>
到</VehicleActivity>
【参考方案1】:
这是一个示例 VehicleActivity
类 - 请注意,它不会处理任何错误,例如缺少 XML 标记或无法解析的日期,您应该自己添加这些错误。
class VehicleActivity
VehicleActivity(
this.recordedAtTime,
this.itemIdentifier,
this.validUntilTime,
);
DateTime? recordedAtTime;
String? itemIdentifier;
DateTime? validUntilTime;
factory VehicleActivity.fromElement(XmlElement vaElement) => 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) => VehicleActivity.fromElement(e))
.toList();
print(allActivities);
【讨论】:
感谢您的回复。第一个问题模型类在哪里?我应该像我的 Json 模型一样将它放在单独的.dart
文件中吗? 2,修改后的xml
调用如何适应我的Https调用,我是否将它放在fetch
方法中的调用之后,xml2json
解析在哪里?
如何构建代码取决于您,但将模型类分开是有意义的。是的,用response.body
或utf8.decode(response.bodyBytes)
替换读取文件 - 我更新了答案以显示这一点。以上是关于为 API 调用 Xml2Json 制作 Json 模型的主要内容,如果未能解决你的问题,请参考以下文章