解析Swift中具有多个相同标识符的JSON



我试图从RestAPI解析JSON数据,该API为我提供挪威的能源数据(https://driftsdata.statnett.no/restapi/ProductionConsumption/GetLatestDetailedOverview)

<ProductionConsumptionOverviewViewModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Statnett.Driftsdata.RestApi.Models">
<ConsumptionData>
...
</ConsumptionData>
<Headers>
...
</Headers>
<HydroData>
<ProdConsOverViewModelItem>
<style>hydro</style>
<textTranslationId>General.Hydro</textTranslationId>
<titleTranslationId i:nil="true"/>
<value/>
</ProdConsOverViewModelItem>
<ProdConsOverViewModelItem>
<style i:nil="true"/>
<textTranslationId i:nil="true"/>
<titleTranslationId>ProductionConsumption.HydroSEDesc</titleTranslationId>
<value>4 840</value>

我知道它读起来像XML,但文档中说的是JSON,所以就这样吧。我在阅读它和XML时遇到了同样的问题

我设法很好地读取了JSON响应,但我遇到了麻烦;向下挖掘";因为不同区域的标识符是相同的。比方说,我想要下面水力发电的数据(见屏幕截图(。我该怎么得到它?Ive尝试设置[titleTranslationId]=="生产消费。HydroSEDesc";但那没用。

它看起来像XML,但文档上写的是JSON?这就是为什么我试图将其视为JSON。

<ProductionConsumptionOverviewViewModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Statnett.Driftsdata.RestApi.Models">
<ConsumptionData>
...
</ConsumptionData>
<Headers>
...
</Headers>
<HydroData>
<ProdConsOverViewModelItem>
<style>hydro</style>
<textTranslationId>General.Hydro</textTranslationId>
<titleTranslationId i:nil="true"/>
<value/>
</ProdConsOverViewModelItem>
<ProdConsOverViewModelItem>
<style i:nil="true"/>
<textTranslationId i:nil="true"/>
<titleTranslationId>ProductionConsumption.HydroSEDesc</titleTranslationId>
<value>4 840</value>

API响应屏幕截图

我使用SwiftyJSON来处理响应。

我找到了一些其他的踏板,但无法让它为我工作。有人能帮忙吗?这是我的代码:

func getEnergyData(url: String){
AF.request(url, method: .get).responseJSON{ response in
switch response.result {
case .success(let json):

print("json success")
//print(json)
let energyJSON : JSON = JSON(response.result)
self.updateEnergyData(json: energyJSON)


case .failure(let error):
print(error)
}

}


}

试图解析它:

func updateEnergyData(json : JSON){

if let results = json["ProductionConsumptionOverviewViewModel"]["HydroData"]["ProdConsOverViewModelItem"]["value"].double{
print(results)
}
else{
print("parse fail")
} 
}       
}

通过浏览器访问此端点时,API返回XML,否则返回JSON。

不需要SwiftyJSON或其他库,而是使用Swift的Codable协议。

例如,制作一个表示要解码的对象的结构:

struct HydroData: Decodable {
let value: String
let textTranslationId: String?
let titleTranslationId: String?
let style: String?
}

还有另一个从阵列中获取这些对象的方法:

struct HydroResult: Decodable {
let HydroData: [HydroData]
}

然后,一旦您从端点下载了数据,就对其进行解码,并使用filter在数组中找到您需要的对象:

let url = URL(string: "https://driftsdata.statnett.no/restapi/ProductionConsumption/GetLatestDetailedOverview")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
print("No data")
return
}
do {
let result = try JSONDecoder().decode(HydroResult.self, from: data)
if let seDesc = result.HydroData.filter({ $0.titleTranslationId == "ProductionConsumption.HydroSEDesc" }).first {
print(seDesc.value)
} else {
print("Error: no value")
}
} catch {
print(error.localizedDescription)
}
}
task.resume()

请注意,value的返回类型是String,其中的数字已经格式化,因此您无法直接将它们转换为Int或Double,因此您必须使用自定义格式化程序,但这是一个完全不同的主题

最新更新