/json_extractor

A library for schema-driven extracting and flattening JSON values with nested maps and lists support.

Primary LanguageDartBSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

Dart Tests pub package package publisher

Extracting nested JSON values

json_extractor is a miniature library providing the functionality of schema-driven extracting and flattening JSON values. Supports nested maps and lists and outputs data as a one-layered Map with a user-defined structure.

Features

  • Extracting deeply nested maps and lists in any nesting order.
  • Simple path-like schemas: user_names: users.user.name.
  • Compile-time constant reusable JsonExtractor instances.
  • Simple flat maps with only needed data as a result.

Getting started

To start, install the package, import JsonExtractor class, and create a schema for it. Then, create a JsonExtractor object with the created schema and use its process method to extract values:

// prefer constant initialization
const extractor = JsonExtractor(schema);
final res = extractor.process(json);

That will extract the values from the given paths in the schema

Usage

When working with deeply nested maps with internal lists, it's necessary to create complex nested get-key and Iterable.map invocations:

final pastry = {
  'itemIds': pastryMap['items'].map((map) => map['item']['id']), // almost ok
  'itemBatters': pastryMap['items'].map((map) => map['item']['batters']['batter']), // worse
  'itemBatterTypes': pastryMap['items'].map((map) => map['item']['batters']['batter'].map((bMap) => bMap['type'])) // oh
};

With JsonExtractor it can be simplified in the way below:

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 Arrays

REST APIs often supply JSON arrays to represent a collection of records. JsonExtractor can be used to extract values from arrays using processAsList method of the extractor. It takes a List and applies the schema to each of the elements in the list. It returns a list of the extracted maps:

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}]

Consider a situation in which you need to extract only a list of values and don't need a map at all. In this case, extract: true option can be used as follows:

const extractor = JsonExtractor({'anything': 'name.nickname'}); // instead of 'anything' can be literally anything 
                                                                // as this key will be extracted
// using the data from the previous example
extractor.processAsList(data, extract: true); // [mitryp, kathalie]

More examples can be found in the example/json_extractor_example.dart file.

Schema

Schema is a Map<String, String> in which keys are used as keys in the resulting map, and the values are the paths to the values in the processed maps.

Paths are the keywords divided by the dots: key1.key2.key3....

The keywords can lead through nested maps and lists: mapKey.listKey.innerMapKey....

Issues and improvement suggestions

Feel free to open new issues and PRs at the project's GitHub.