Flutter JSON路径解析插件json_path的使用

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

Flutter JSON路径解析插件json_path的使用

简介

json_path 是一个用于在Dart中执行JSONPath查询表达式的库,它遵循RFC 9535标准。该库允许你通过简洁的字符串语法从给定的JSON值中选择和提取数据。

安装

在你的 pubspec.yaml 文件中添加依赖:

dependencies:
  json_path: ^最新版本号

然后运行 flutter pub get 或者 dart pub get 来安装包。

使用示例

示例代码

以下是一个完整的示例,展示了如何使用 json_path 插件来解析和操作JSON数据:

import 'dart:convert';
import 'package:json_path/json_path.dart';

void main() {
  // 解析JSON字符串为Map对象
  final document = jsonDecode('''
  {
    "store": {
      "book": [
        {
          "category": "reference",
          "author": "Nigel Rees",
          "title": "Sayings of the Century",
          "price": 8.95
        },
        {
          "category": "fiction",
          "author": "Evelyn Waugh",
          "title": "Sword of Honour",
          "price": 12.99
        },
        {
          "category": "fiction",
          "author": "Herman Melville",
          "title": "Moby Dick",
          "isbn": "0-553-21311-3",
          "price": 8.99
        },
        {
          "category": "fiction",
          "author": "J. R. R. Tolkien",
          "title": "The Lord of the Rings",
          "isbn": "0-395-19395-8",
          "price": 22.99
        }
      ],
      "bicycle": {
        "color": "red",
        "price": 19.95
      }
    }
  }  
  ''');

  // 获取所有价格
  print('All prices in the store, by JSONPath:');
  JsonPath(r'$..price')
      .read(document)
      .map((match) => '${match.path}:\t${match.value}')
      .forEach(print);

  // 使用JSON Pointer获取所有价格
  print('\nSame, by JSON Pointer:');
  JsonPath(r'$..price')
      .read(document)
      .map((match) => '${match.pointer}:\t${match.value}')
      .forEach(print);

  // 只打印价格值
  print('\nSame, but just the values:');
  JsonPath(r'$..price').readValues(document).forEach(print);

  // 打印价格低于10的书籍标题
  print('\nBooks under 10:');
  JsonPath(r'$.store.book[?@.price < 10].title')
      .readValues(document)
      .forEach(print);

  // 打印有ISBN的书籍标题
  print('\nBooks with ISBN:');
  JsonPath(r'$.store.book[?@.isbn].title').readValues(document).forEach(print);

  // 打印价格低于10且有ISBN的书籍标题
  print('\nBooks under 10 with ISBN:');
  JsonPath(r'$.store.book[?@.price < 10 && @.isbn].title')
      .readValues(document)
      .forEach(print);

  // 打印标题包含"the"的书籍标题
  print('\nBooks with "the" in the title:');
  JsonPath(r'$.store.book[?search(@.title, "the")].title')
      .readValues(document)
      .forEach(print);

  // 打印与最后一本书类别相同的书籍标题
  print('\nBooks with the same category as the last one:');
  JsonPath(r'$.store.book[?@.category == $.store.book[-1].category].title')
      .readValues(document)
      .forEach(print);
}

说明

  • JsonPath(r'$..price'):查询所有价格。
  • JsonPath(r'$.store.book[?@.price < 10].title'):查询价格低于10的书籍标题。
  • JsonPath(r'$.store.book[?@.isbn].title'):查询有ISBN的书籍标题。
  • JsonPath(r'$.store.book[?@.price < 10 && @.isbn].title'):查询价格低于10且有ISBN的书籍标题。
  • JsonPath(r'$.store.book[?search(@.title, "the")].title'):查询标题包含"the"的书籍标题。
  • JsonPath(r'$.store.book[?@.category == $.store.book[-1].category].title'):查询与最后一本书类别相同的书籍标题。

数据操作

每个 JsonPathMatch 对象包含 .pointer 属性,这是一个有效的 JSON Pointer,可以用来修改引用的值。如果你只需要操作JSON数据,可以考虑使用 JSON Pointer 实现

用户自定义函数

你可以通过实现 Fun1Fun2 接口来自定义函数,并将其传递给 JsonPathParser。例如:

import 'package:json_path/fun_sdk.dart';

class MyFunction extends Fun1<String> {
  const MyFunction();

  @override
  String apply(String arg) {
    return arg.toUpperCase();
  }

  @override
  String get name => 'my_function';
}

final parser = JsonPathParser(functions: [const MyFunction()]);
final jsonPath = parser.parse(r'$[?my_function(@)]');

内置非标准函数

json_path 包含一些非标准但有用的函数,如:

  • count(<NodeList>):返回由参数选择的节点数量。
  • index(<SingularNodeList>):返回数组元素在其父数组中的索引。
  • key(<SingularNodeList>):返回对象元素在其父对象中的键。
  • is_array(<Maybe>)is_boolean(<Maybe>)is_number(<Maybe>)is_object(<Maybe>)is_string(<Maybe>):分别检查值是否为数组、布尔值、数字、对象或字符串。
  • reverse(<Maybe>):反转字符串。
  • siblings(<NodeList>):返回节点的兄弟节点。
  • xor(<bool>, <bool>):返回两个布尔参数的异或结果。

要使用这些函数,导入 package:json_path/fun_extra.dart 并将它们传递给 JsonPath 构造函数。

参考资料

通过以上内容,你应该能够熟练使用 json_path 插件来解析和操作JSON数据。如果有任何问题或需要进一步的帮助,请随时提问!


更多关于Flutter JSON路径解析插件json_path的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter JSON路径解析插件json_path的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter中使用json_path插件来解析JSON路径的示例代码。这个示例展示了如何配置Flutter项目以使用该插件,以及如何使用它来解析JSON数据。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  json_path: ^0.5.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

2. 导入插件

在你的Dart文件中导入json_path插件:

import 'package:json_path/json_path.dart';

3. 使用json_path解析JSON

以下是一个完整的示例,展示了如何使用json_path插件来解析JSON数据:

import 'package:flutter/material.dart';
import 'package:json_path/json_path.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('JSON Path Example'),
        ),
        body: Center(
          child: JsonPathExample(),
        ),
      ),
    );
  }
}

class JsonPathExample extends StatelessWidget {
  final String jsonData = '''
  {
    "store": {
      "book": [
        { "category": "reference",
          "author": "Nigel Rees",
          "title": "Sayings of the Century",
          "price": 8.95
        },
        { "category": "fiction",
          "author": "Evelyn Waugh",
          "title": "Sword of Honour",
          "price": 12.99
        },
        { "category": "fiction",
          "author": "Herman Melville",
          "title": "Moby Dick",
          "isbn": "0-553-21311-3",
          "price": 8.99
        },
        { "category": "fiction",
          "author": "J. Tolkien",
          "title": "The Lord of the Rings",
          "isbn": "0-395-19395-8",
          "price": 22.99
        }
      ],
      "bicycle": {
        "color": "red",
        "price": 19.95
      }
    }
  }
  ''';

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Books with price less than 10:'),
        Expanded(
          child: SingleChildScrollView(
            child: JsonOutput(
              jsonPath: JsonPath.parse('$..book[?(@.price < 10)]'),
              jsonData: jsonData,
            ),
          ),
        ),
        SizedBox(height: 20),
        Text('All ISBN numbers:'),
        Expanded(
          child: SingleChildScrollView(
            child: JsonOutput(
              jsonPath: JsonPath.parse('$..book[*].isbn'),
              jsonData: jsonData,
            ),
          ),
        ),
      ],
    );
  }
}

class JsonOutput extends StatelessWidget {
  final JsonPath jsonPath;
  final String jsonData;

  JsonOutput({required this.jsonPath, required this.jsonData});

  @override
  Widget build(BuildContext context) {
    List<dynamic> result = jsonPath.read(jsonDecode(jsonData)).toList();
    return Text(
      result.map((e) => e.toString()).join('\n'),
      style: TextStyle(fontSize: 16),
    );
  }
}

解释

  1. 添加依赖:在pubspec.yaml中添加json_path依赖。
  2. 导入插件:在Dart文件中导入json_path
  3. JSON数据:定义一个JSON字符串jsonData
  4. JsonPath解析
    • 使用JsonPath.parse来定义JSON路径表达式。
    • 使用jsonPath.read(jsonDecode(jsonData)).toList()来解析JSON并获取结果。
  5. 展示结果:将解析结果展示在Text组件中。

这个示例展示了如何获取所有价格低于10的书籍以及所有书籍的ISBN号码。你可以根据需要修改JSON路径表达式来获取不同的数据。

回到顶部