Mutating JSON Files

Note

All JSON files used in examples in this section can be found here Sample Files

  • JsonQL expressions are used in one or many JSON files. JsonQL evaluates JsonQL expressions and loads the parsed JSON files with expressions replaced with calculated JSON objects into an instance of JsonQL.Compilation.ICompilationResult.

  • The property CompiledJsonFiles contains collection of JsonQL.Compilation.ICompiledJsonData: one per loaded file.

  • JsonQL.Compilation.ICompiledJsonData represents mutated JSON files (i.e., mutated by using JsonQL expressions).

  • The property CompilationErrors contains collection of JsonQL.Compilation.ICompilationErrorItem with error details if any.

  • If many JSON files are specified the following rules and techniques are used: - Parent/child relationships between JSON files are maintained, and parent JSON files are evaluated before child JSON files are evaluated. - Lookup of JSON values specified in JsonQL expressions starts in JSON containing the expression first, and then in parent JSON files.

As an example lets consider the following JSON files. These files will be evaluated loaded by JsonQL in C# code snippet below which will evaluate the files on top of the list as parent JSON files of files that appear later.

Note

JsonQL Expressions start with ‘$’. Example “$value(Employees.Select(x => x.Salary >= 100000))”.

{
  "AdditionalCompanyNames": [ "Atlantic Transfers, Inc" ],

  "comments1": "'FilteredCompanyNames' is in parent JSON 'Parameters.json'.",
  "comments2": "We filter companies that are either in FilteredCompanyNames or in AdditionalCompanyNames in this file.",
  "FilteredCompanies": "$value(Companies.Where(c => Any(FilteredCompanyNames, x => x == c.CompanyData.Name) || Any(AdditionalCompanyNames, x => x == c.CompanyData.Name)))"
}
  • MainExample/Example.json - a JSON file shown below with JsonQL expressions that reference JSON objects in this file as well as in files listed above. The expressions in this file can also reference JSON objects from files above that are generated using JSON expressions (for example companies in FilteredCompanies in FilteredCompanies.json)

{
  "FilteredCountryNames": [ "United States", "Canada", "Australia" ],

  "FilteredCountryData": "$value(Countries.Where(c => Any(FilteredCountryNames.Where(x => x == c.Name))).Select(c => Concatenate('Name:', c.Name, ', Population:', c.Population)))",

  "comments": "'FilteredCompanies' array used in JsonQL expressions below is in parent JSON FilteredCompanies.json",
  "FilteredCompanyAddresses": {
    "comments": "'FilteredCompanies' array is in parent JSON FilteredCompanies.json",
    "addresses": "$value(FilteredCompanies.Where(c => c.CompanyData.CEO != 'John Malkowich').Select(x => x.Address))"
  },

  "FilteredCompanyEmployees": "$value(FilteredCompanies.Select(c => c.Employees.Where(e => e.Name !=  'John Smith')))",
  "FilteredCompanyEmployeeAddresses": "$value(FilteredCompanies.Select(c => c.Employees.Select(x => x.Address)))"
}

The code snippet below shows how to load the the five files above in such a way that JsonQL loads Countries.json first, then loads Companies.json as a child of Countries.json (i.e., can use JsonQL expressions that reference JSON objects in evaluated file Countries.json), then loads Parameters.json, FilteredCompanies.json and finally loads MainExample/Example.json using similar parent child relationship rules.

string[] sharedExamplesFolderPath = new string[] { "DocFiles", "MutatingJsonFiles", "Examples"};

var parametersJsonTextData = new JsonTextData("Parameters",
    LoadJsonFileHelpers.LoadJsonFile("Parameters.json", sharedExamplesFolderPath));

// countriesJsonTextData uses parametersJsonTextData for parameter parentJsonTextData
var countriesJsonTextData = new JsonTextData("Countries",
    LoadJsonFileHelpers.LoadJsonFile("Countries.json", sharedExamplesFolderPath), parametersJsonTextData);

var companiesJsonTextData = new JsonTextData("Companies",
    LoadJsonFileHelpers.LoadJsonFile("Companies.json", sharedExamplesFolderPath), countriesJsonTextData);

var filteredCompaniesJsonTextData = new JsonTextData("FilteredCompanies",
    LoadJsonFileHelpers.LoadJsonFile("FilteredCompanies.json",  sharedExamplesFolderPath), companiesJsonTextData);

// Set the value of jsonCompiler to an instance of JsonQL.Compilation.IJsonCompiler here.
// The value of JsonQL.Compilation.JsonCompiler is normally created by Dependency Injection container
// and it is normally configured as a singleton.
JsonQL.Compilation.IJsonCompiler jsonCompiler = null!;

var result = jsonCompiler.Compile(new JsonTextData("Example",
    this.LoadExampleJsonFile("Example.json"), filteredCompaniesJsonTextData));