为 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 还是数据检索,它都会在 nullvehicleActivity 返回

电话

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数据在树&lt;/VehicleActivity&gt;&lt;/VehicleActivity&gt; 【参考方案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.bodyutf8.decode(response.bodyBytes) 替换读取文件 - 我更新了答案以显示这一点。

以上是关于为 API 调用 Xml2Json 制作 Json 模型的主要内容,如果未能解决你的问题,请参考以下文章

python xml2json

使用 $.xml2Json 返回一个复杂的对象

C# xml2json

vue中引入x2js(针对xml、json数据进行转换处理)

尝试将来自 API 的 JSON 数据显示为数组

React 中的多个 API 调用