简体   繁体   English

使用未知密钥对JSON进行序列化

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM