[英]Serialization of JSON with unknown key
I'm using the json_serializable pub package for all my RESTful API needs, and it worked great, but now i'm trying to serialize content from Wikipedia. 我正在使用json_serializable pub包来满足我的所有RESTful API需求,并且效果很好,但是现在我正尝试从Wikipedia序列化内容。
My problem is with the response structure, one of the keys is unknown beforehand and dynamic according to the returned page ID, here's an example: 我的问题是响应结构,其中一个键是事先未知的,并且根据返回的页面ID是动态的,这是一个示例:
I would like to get only the intro part of a page, my query is: https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&redirects=1&exintro=1&explaintext=1&titles=Stack%20Overflow 我只想获取页面的介绍部分,我的查询是: https : //en.wikipedia.org/w/api.php?action= query &format=json&prop=extracts&redirects=1&exintro=1&explaintext=1&titles=Stack%20Overflow
The response will be: 响应将是:
{
"batchcomplete": "",
"query": {
"pages": {
"21721040": {
"pageid": 21721040,
"ns": 0,
"title": "Stack Overflow",
"extract": "Stack Overflow is a privately held website, the flagship site of ......."
}
}
}
}
Eventually i would like to get only the internal extract
string, but "on my way" there i have the page id under pages
. 最终,我只想获取内部extract
字符串,但是在“途中”,我在pages
下有页面ID。
I can't find how i can get an object when i cannot tell what is the key, neither using json_serializable package nor explicitly writing the JSON import code. 我无法使用json_serializable软件包或显式编写JSON导入代码时都无法知道密钥是什么,所以我找不到如何获取对象。 Is it possible? 可能吗?
PS, i do think i found a way that required two API calls - if i add the indexpageids flag and set it to true, i will receive an additional dictionary entry called pageids
with the page id numbers as string , then i can use the retrieved string in the second API call. PS,我确实认为我发现了一种需要两次API调用的方法-如果我添加indexpageids标志并将其设置为true, 我将收到一个名为pageids
的附加字典条目,其页面ID号为string ,那么我可以使用检索到的第二个API调用中的字符串。
I still don't know the exact way i'll do it but i'm pretty sure it's possible, but sending 2 API requests every time is expensive and i would like to know if there's a more elegant way to do it. 我仍然不知道确切的方法,但是我很确定这是可能的,但是每次发送2个API请求都是很昂贵的,我想知道是否还有一种更优雅的方法。
Make sure that you use the latest version of json_serializable. 确保您使用最新版本的json_serializable。 Use a Map<String, Page>
for key-value pairs: 将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);
}
Just to prove that it works, here is what json_serializable is generating: 只是为了证明它有效,这是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>))));
}
You can get keys of json & then use that key to fetch value as 您可以获取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"];
How would you do if you have another level of dynamic keys inside the dynamic key? 如果动态密钥中还有另一级动态密钥,该怎么办? I had to edit the generated json_serializable for my second class to use json only instead of the generated json['key']. 我必须为第二个类编辑生成的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>))));
}
It feels like there is some better way? 感觉有更好的方法吗? Because this generated code gets overwritten everytime I make changes in any file and run generator.. 因为每次我在任何文件中进行更改并运行generator时,生成的代码都会被覆盖。
Im new to SO so I cant rate answers and write comments. 我是新来的人,所以我无法评价答案和发表评论。 But boformer's answer helped me but then I ran into this second question. 但是boformer的回答对我有所帮助,但后来我遇到了第二个问题。
Edit: I found the solution by trial and error, used: 编辑:我通过反复试验找到了解决方案,使用:
class Query {
final Map<String, Map<String, SecondPage>> pages;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.