我想反序列化一些包含文章信息列表的JSON数据
{
"data": [
{
"id": 1,
"title": "First article",
"createdDate": "2022-03-20T11:46:00",
"content": "Markdown content",
"author": 1,
"category": 1
},
{
"id": 2,
"title": "Second article",
"createdDate": "2022-03-20T11:46:00",
"content": "Markdown content",
"author": 1,
"category": 1
}
]
}无论请求是什么,顶层都将有一个名为data的键。
因此,我创建了一个名为Entry的泛型类。
import 'package:json_annotation/json_annotation.dart';
part 'Entry.g.dart';
@JsonSerializable(genericArgumentFactories: true)
class Entry<TData> {
Entry(this.data);
TData data;
factory Entry.fromJson(Map<String, dynamic> json,TData Function(dynamic json) fromJsonTData) => _$EntryFromJson(json,fromJsonTData);
Map<String, dynamic> toJson(Object? Function(TData value) toJsonTData) => _$EntryToJson(this,toJsonTData);
}对于一篇文章,我创建了一个名为NovelData的类
import 'dart:convert';
import 'dart:core';
import 'package:json_annotation/json_annotation.dart';
import 'Entry.dart';
part 'NovelData.g.dart';
@JsonSerializable(genericArgumentFactories: true)
class NovelData {
NovelData(this.id, this.title, this.createdDate, this.content, this.author, this.category);
int id;
String title;
String createdDate;
String content;
int author;
int category;
factory NovelData.fromJson(Map<String, dynamic> json) =>
_$NovelDataFromJson(json);
Map<String, dynamic> toJson() => _$NovelDataToJson(this);
}现在,如果我想使用像Entry<List<Novel>>>这样的类型来反序列化上面的JSON数据,我应该做什么?
发布于 2022-05-15 19:44:33
您可以通过数据的完整路径访问它们。
数据的完整路径:映射=>键data =>数组=>数组索引=>映射
{}.data.[].0.{}
只需要上一节课。
import 'package:fast_json/fast_json_selector.dart' as parser;
void main() async {
final path = '{}.data.[].0.{}';
final pathLevel = path.split('.').length;
final items = <Novel>[];
void select(parser.JsonSelectorEvent event) {
if (event.levels.length == pathLevel) {
if (event.levels.join('.') == path) {
final item = Novel.fromJson(event.lastValue as Map);
items.add(item);
event.lastValue = null;
}
}
}
parser.parse(_json, select: select);
print(items.join('\n'));
}
final _json = '''
{
"data": [
{
"id": 1,
"title": "First article",
"createdDate": "2022-03-20T11:46:00",
"content": "Markdown content",
"author": 1,
"category": 1
},
{
"id": 2,
"title": "Second article",
"createdDate": "2022-03-20T11:46:00",
"content": "Markdown content",
"author": 1,
"category": 1
}
]
}''';
class Novel {
final int id;
final String title;
Novel({required this.id, required this.title});
@override
String toString() {
return title;
}
static Novel fromJson(Map json) {
return Novel(
id: json['id'] as int,
title: json['title'] as String,
);
}
}输出:
First article
Second article您可以在将数据添加到列表之前获取数据。结果也没什么不同。只是另一条通往数据的路径。
void main() async {
final path = '{}.data.[].0';
final pathLevel = path.split('.').length;
final items = <Novel>[];
void select(parser.JsonSelectorEvent event) {
if (event.levels.length == pathLevel) {
if (event.levels.join('.') == path) {
final item = Novel.fromJson(event.lastValue as Map);
items.add(item);
event.lastValue = null;
}
}
}
parser.parse(_json, select: select);
print(items.join('\n'));
}此事件遵循对象创建事件(在较低的事件级别上):
JsonHandlerEvent.endObject => JsonHandlerEvent.element
您可以在将数据添加到列表后获取数据。但不会有那么高的效率。
void main() async {
final path = '{}.data.[]';
final pathLevel = path.split('.').length;
final items = <Novel>[];
void select(parser.JsonSelectorEvent event) {
if (event.levels.length == pathLevel) {
if (event.levels.join('.') == path) {
final list = event.lastValue as List;
items.addAll(list.map((e) => Novel.fromJson(e as Map)));
list.clear();
}
}
}
parser.parse(_json, select: select);
print(items.join('\n'));
}JsonHandlerEvent.endObject => JsonHandlerEvent.element => JsonHandlerEvent.endArray
甚至从属性data。效率很低,因为所有的数据都存储在内存中。
void main() async {
final path = '{}.data';
final pathLevel = path.split('.').length;
final items = <Novel>[];
void select(parser.JsonSelectorEvent event) {
if (event.levels.length == pathLevel) {
if (event.levels.join('.') == path) {
final list = event.lastValue as List;
items.addAll(list.map((e) => Novel.fromJson(e as Map)));
event.lastValue = null;
}
}
}
parser.parse(_json, select: select);
print(items.join('\n'));
}JsonHandlerEvent.endObject => JsonHandlerEvent.element => JsonHandlerEvent.endArray => JsonHandlerEvent.endKey
我甚至不会写关于最后一层的文章。这种低效的方式是没有意义的。然而,在前一个版本中也是如此。
JsonHandlerEvent.endObject => JsonHandlerEvent.element => JsonHandlerEvent.endArray => JsonHandlerEvent.endKey => JsonHandlerEvent.endObject
发布于 2022-05-14 15:26:17
有一个网站,它从json自动生成所有所需的代码。下面是一个例子:
// To parse this JSON data, do
//
// final entry = entryFromJson(jsonString);
import 'dart:convert';
Entry entryFromJson(String str) => Entry.fromJson(json.decode(str));
String entryToJson(Entry data) => json.encode(data.toJson());
class Entry {
Entry({
this.data,
});
List<Datum> data;
factory Entry.fromJson(Map<String, dynamic> json) => Entry(
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.id,
this.title,
this.createdDate,
this.content,
this.author,
this.category,
});
int id;
String title;
DateTime createdDate;
String content;
int author;
int category;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
title: json["title"],
createdDate: DateTime.parse(json["createdDate"]),
content: json["content"],
author: json["author"],
category: json["category"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"createdDate": createdDate.toIso8601String(),
"content": content,
"author": author,
"category": category,
};
}发布于 2022-05-16 04:47:23
您可以尝试我的jsonize包,它将处理任何TData类,无论它们在Entry数据列表中的哪个位置。
import 'package:jsonize/jsonize.dart';
abstract class TData {}
class Entry implements Jsonizable {
Entry({
required this.data,
});
factory Entry.empty() => Entry(data: []);
List<TData> data;
@override
String get jsonClassCode => "Entry";
@override
Entry fromJson(json) => Entry(data: List<TData>.from(json["data"]));
@override
Map<String, dynamic> toJson() => {"data": data};
}
class NovelData extends TData implements Jsonizable {
NovelData({
required this.id,
required this.title,
required this.createdDate,
required this.content,
required this.author,
required this.category,
});
factory NovelData.empty() => NovelData(
id: 0,
title: "",
createdDate: DateTime(0),
content: "",
author: 0,
category: 0);
int id;
String title;
DateTime createdDate;
String content;
int author;
int category;
@override
String get jsonClassCode => "NovelData";
@override
NovelData fromJson(json) => NovelData(
id: json["id"],
title: json["title"],
createdDate: json["createdDate"],
content: json["content"],
author: json["author"],
category: json["category"],
);
@override
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"createdDate": createdDate,
"content": content,
"author": author,
"category": category,
};
}
main() {
Jsonize.registerClass(Entry.empty());
Jsonize.registerClass(NovelData.empty());
NovelData novel1 = NovelData(
id: 1,
title: "First article",
createdDate: DateTime.now(),
content: "Markdown content",
author: 1,
category: 1);
NovelData novel2 = NovelData(
id: 2,
title: "Second article",
createdDate: DateTime.now(),
content: "Markdown content",
author: 1,
category: 1);
Entry myEntry = Entry(data: [novel1, novel2]);
String myEntryJson = Jsonize.toJson(myEntry);
print(myEntryJson);
Entry entryBackToLife = Jsonize.fromJson(myEntryJson);
print(entryBackToLife);
}jsonize可以做得更像处理枚举。就你而言,好处是:
https://stackoverflow.com/questions/72241580
复制相似问题