我正在使用json_serializable pub package满足所有RESTful API的需求,并且效果很好,但是现在我正尝试从Wikipedia序列化内容。
我的问题是响应结构,其中一个键是事先未知的,并且根据返回的页面ID是动态的,这是一个示例:
我只想获取页面的简介部分,我的查询是: https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&redirects=1&exintro=1&explaintext=1&titles=Stack%20Overflow
响应将是:
{
"batchcomplete": "",
"query": {
"pages": {
"21721040": {
"pageid": 21721040,
"ns": 0,
"title": "Stack Overflow",
"extract": "Stack Overflow is a privately held website, the flagship site of ......."
}
}
}
}
最终,我只想获取内部的extract
字符串,但是在“按我的方式”那里,我的页面ID在pages
下。
我无法使用json_serializable package或显式编写JSON导入代码时都无法知道密钥是什么,因此我无法找到对象。有可能吗?
PS,我确实认为我找到了一种需要两次API调用的方法-如果我添加 indexpageids 标志并将其设置为true,i will receive an additional dictionary entry called pageids
with the page id numbers as string,则可以使用检索到的字符串在第二个API调用中。
我仍然不知道确切的方法,但是我很确定这是可能的,但是每次发送2个API请求都很昂贵,我想知道是否还有一种更优雅的方法
答案 0 :(得分:0)
确保使用最新版本的json_serializable。将Map<String, Page>
用于键值对:
@JsonSerializable()
class Query {
final Map<String, Page> pages;
Query(this.pages);
factory Query.fromJson(Map<String, dynamic> json) => _$QueryFromJson(json);
Map<String, dynamic> toJson() => _$QueryToJson(this);
}
只是为了证明它有效,这就是json_serializable生成的内容:
Query _$QueryFromJson(Map<String, dynamic> json) {
return new Query((json['pages'] as Map<String, dynamic>)?.map((k, e) =>
new MapEntry(
k, e == null ? null : new Page.fromJson(e as Map<String, dynamic>))));
}
答案 1 :(得分:0)
您可以获取json键,然后使用该键将值提取为
var response = await http.get(API_ENDPOINT);
var responseJson = json.decode(response.body);
Map<String, dynamic> json =responseJson['query']['pages'];
String pageId = json.keys.toList()[0]; // 0 for first page, you can iterate for multiple pages
firstPage = json[pageId];
String title = firstPage["title"];
答案 2 :(得分:0)
如果动态密钥中有另一级动态密钥,您将如何处理?我必须为第二个类编辑生成的json_serializable,以仅使用json而不是生成的json ['key']。
Page _$PageFromJson(Map<String, dynamic> json) {
return new Page((json as Map<String, dynamic>)?.map((k, e) =>
new MapEntry(
k, e == null ? null : new SecondPage.fromJson(e as Map<String, dynamic>))));
}
感觉有更好的方法吗?因为每次我在任何文件中进行更改并运行generator时,生成的代码都会被覆盖。
我是新手,所以我无法对答案进行评分和发表评论。但是boformer的回答对我有所帮助,但后来我遇到了第二个问题。
编辑:我通过反复试验找到了解决方案,使用了:
class Query {
final Map<String, Map<String, SecondPage>> pages;