Flutter JSON数据提取插件json_extractor的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter JSON数据提取插件json_extractor的使用

json_extractor 是一个微型库,提供了基于模式驱动的提取和展平 JSON 值的功能。它支持嵌套的映射和列表,并以用户定义的结构输出为一层映射。

特性

  • 提取任意深度嵌套的映射和列表。
  • 简单的路径样式的模式:user_names: users.user.name
  • 编译时常量可重用的 JsonExtractor 实例。
  • 简单的一层映射,只包含所需的数据作为结果。

开始使用

首先,安装包,导入 JsonExtractor 类,并为其创建一个模式(schema)。然后,创建一个 JsonExtractor 对象并使用其 process 方法来提取值:

// 更倾向于常量初始化
const extractor = JsonExtractor(schema);
final res = extractor.process(json);

这将从给定模式中的路径提取值。

使用示例

在处理深层嵌套映射和内部列表时,通常需要创建复杂的嵌套获取键和 Iterable.map 调用:

final pastry = {
  'itemIds': pastryMap['items'].map((map) => map['item']['id']), // 几乎可以了
  'itemBatters': pastryMap['items'].map((map) => map['item']['batters']['batter']), // 更糟糕
  'itemBatterTypes': pastryMap['items'].map((map) => map['item']['batters']['batter'].map((bMap) => bMap['type'])) // 哦
};

使用 JsonExtractor 可以简化上述过程:

const schema = {
  'itemIds': 'items.item.id',
  'itemBatters': 'items.item.batters.batter',
  'itemBatterTypes': 'items.item.batters.batter.type'
};
final pastry = const JsonExtractor(schema).process(pastryMap);

JSON 数组

REST API 经常通过 JSON 数组来表示一组记录。JsonExtractor 可以使用提取器的 processAsList 方法来提取数组中的值。它接受一个列表:

const data = [
  {
    'id': 1,
    'name': {'name': 'Dmytro', 'nickname': 'mitryp'},
  },
  {
    'id': 2,
    'name': {'name': 'Kateryna', 'nickname': 'kathalie'},
  },
];

const extractor = JsonExtractor({'id': 'id', 'nickname': 'name.nickname'});
extractor.processAsList(data); // [{id: 1, nickname: mitryp}, {id: 2, nickname: kathalie}]

如果只需要提取值列表而不需要完整的映射,可以使用 extract: true 选项:

const extractor = JsonExtractor({'anything': 'name.nickname'}); // 'anything' 可以是任何字符串
                                                            // 因为此键将被提取
// 使用上面的例子中的数据
extractor.processAsList(data, extract: true); // [mitryp, kathalie]

更多示例可以在 example/json_extractor_example.dart 文件中找到。

模式

模式是一个 Map<String, String>,其中键用于作为结果映射中的键,值是处理映射中值的路径。

路径是用点分隔的关键字:key1.key2.key3...

关键字可以通过嵌套映射和列表进行导航:mapKey.listKey.innerMapKey...

问题与改进建议

如果您遇到任何问题或有改进建议,请在项目的 GitHub 上打开新问题或 PR。

示例代码

import 'package:json_extractor/json_extractor.dart';

/// 可能的服务器响应,包含服务用户的列表。
const serviceUsersJson = {
  'users': [
    {
      'user': {
        'id': 1,
        'name': 'Kathryn',
        'post_ids': [1, 12, 14, 20, 31],
        'is_admin': true
      }
    },
    {
      'user': {
        'id': 2,
        'name': 'Dmytro',
        'post_ids': [2, 17, 21],
        'is_admin': false
      }
    }
    // ... 可能还有更多的用户
  ]
};

/// 返回给定 JSON 中所有用户的 ID 列表。
///
/// 如果 [usersJson] 中没有用户,则返回空列表。
///
List<int> userIds(dynamic usersJson) {
  const extractor = JsonExtractor({'ids': 'users.user.id'});

  final extracted = extractor.process(usersJson);

  return extracted['ids']?.cast<int>() ?? [];
}

/// 返回给定 JSON 中用户的名称列表。
///
/// 如果 [usersJson] 中没有用户,则返回空列表。
///
List<String> userNames(dynamic usersJson) {
  const extractor = JsonExtractor({'names': 'users.user.name'});

  final extracted = extractor.process(usersJson);

  return extracted['names']?.cast<String>() ?? [];
}

/// 返回给定 JSON 中的管理员用户列表。
List<Map> admins(dynamic usersJson) {
  const extractor = JsonExtractor({'users': 'users.user'});

  final extracted = extractor.process(usersJson);

  return extracted['users']
      .where((userMap) => userMap['is_admin'] as bool)
      .cast<Map>()
      .toList();
}

void main() {
  final adminsList = admins(serviceUsersJson);
  final userNamesList = userNames(serviceUsersJson);
  final userIdsList = userIds(serviceUsersJson);

  print('Admins: $adminsList');
  print('User names: $userNamesList');
  print('User ids: $userIdsList');
}

更多关于Flutter JSON数据提取插件json_extractor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter JSON数据提取插件json_extractor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用json_extractor插件来提取JSON数据的示例代码。

首先,你需要在pubspec.yaml文件中添加json_extractor依赖:

dependencies:
  flutter:
    sdk: flutter
  json_extractor: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来获取依赖。

接下来,我们假设有一个JSON数据,并演示如何使用json_extractor来提取数据。

示例JSON数据

{
  "user": {
    "id": 1,
    "name": "John Doe",
    "email": "john.doe@example.com",
    "address": {
      "street": "123 Main St",
      "city": "Anytown",
      "zipcode": "12345"
    }
  }
}

Dart代码示例

首先,我们定义一个模型类来表示JSON数据的结构(虽然json_extractor不强制要求定义模型类,但定义模型类有助于理解数据结构)。

class User {
  final int id;
  final String name;
  final String email;
  final Address address;

  User({required this.id, required this.name, required this.email, required this.address});
}

class Address {
  final String street;
  final String city;
  final String zipcode;

  Address({required this.street, required this.city, required this.zipcode});
}

然后,我们使用json_extractor来提取JSON数据:

import 'package:flutter/material.dart';
import 'package:json_extractor/json_extractor.dart';
import 'dart:convert';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('JSON Extractor Example'),
        ),
        body: Center(
          child: FutureBuilder<User?>(
            future: _fetchAndExtractData(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return CircularProgressIndicator();
              } else if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              }
              if (snapshot.hasData) {
                final User user = snapshot.data!;
                return Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text('ID: ${user.id}'),
                    Text('Name: ${user.name}'),
                    Text('Email: ${user.email}'),
                    Text('Street: ${user.address.street}'),
                    Text('City: ${user.address.city}'),
                    Text('Zipcode: ${user.address.zipcode}'),
                  ],
                );
              } else {
                return Text('No data');
              }
            },
          ),
        ),
      ),
    );
  }

  Future<User?> _fetchAndExtractData() async {
    // 假设这是从网络或其他地方获取的JSON字符串
    String jsonString = '''
    {
      "user": {
        "id": 1,
        "name": "John Doe",
        "email": "john.doe@example.com",
        "address": {
          "street": "123 Main St",
          "city": "Anytown",
          "zipcode": "12345"
        }
      }
    }
    ''';

    // 将JSON字符串转换为Map
    Map<String, dynamic> jsonMap = jsonDecode(jsonString);

    // 使用json_extractor提取数据
    final JsonExtractor extractor = JsonExtractor(jsonMap);
    final int id = extractor.extract('user.id').intValue();
    final String name = extractor.extract('user.name').stringValue();
    final String email = extractor.extract('user.email').stringValue();
    final String street = extractor.extract('user.address.street').stringValue();
    final String city = extractor.extract('user.address.city').stringValue();
    final String zipcode = extractor.extract('user.address.zipcode').stringValue();

    // 创建User对象并返回
    return User(
      id: id,
      name: name,
      email: email,
      address: Address(street: street, city: city, zipcode: zipcode),
    );
  }
}

在这个示例中,我们:

  1. 定义了UserAddress类来表示JSON数据的结构。
  2. _fetchAndExtractData方法中,将JSON字符串转换为Map。
  3. 使用JsonExtractor从Map中提取数据。
  4. 使用提取的数据创建User对象并返回。
  5. FutureBuilder中显示提取的数据。

这个示例展示了如何使用json_extractor插件从JSON数据中提取信息并在Flutter应用中显示。

回到顶部