JmesPath.Net
A fully compliant implementation of JMESPATH for .NetCore
Example
using DevLab.JmesPath;
using Newtonsoft.Json.Linq;
// Json: {"foo": "bar"}
// JmesPath Expression: "foo"
// Result: "bar"
const string input = "{ \"foo\": \"bar\" }";
const string expression = "foo";
var jmes = new JmesPath();
var result = jmes.Transform(input, expression);
System.Diagnostics.Debug.Assert(result == "\"bar\"");
var token = JToken.Parse(result);
var text = token.ToString();
System.Diagnostics.Debug.Assert(text == "bar");
Getting started
Using the parser
JmesPath.Net
uses Newtonsoft.Json to handle JSON and comes with a simple to use parser:
using DevLab.JmesPath;
const string input = @"{ \"foo\": \"bar\" }";
const string expression = "foo";
var jmes = new JmesPath();
var result = jmes.Transform(input, expression);
The JmesPath.Transform
method accepts and produces well formed JSON constructs (object, array or string, boolean, number and null values). In the example above, the result
is a JSON string token, including the quotes.
using Newtonsoft.Json.Linq;
System.Diagnostics.Debug.Assert(result == "\"bar\"");
var token = JToken.Parse(result);
var text = token.ToString();
System.Diagnostics.Debug.Assert(text == "bar");
Using functions
JmesPath.Net
supports the specified builtin functions. Additionaly, the library supports registering custom functions if required.
First, create an assembly and declare a new function:
using DevLab.JmesPath.Functions;
using DevLab.JmesPath.Utils;
using Newtonsof.Json.Linq;
public sealed class SubstringFunction : JmesPathFunction
{
public SubstringFunction()
: base("substring", 2)
{
}
public override void Validate(params JmesPathFunctionArgument[] arguments)
{
base.Validate();
if (arguments.Length != 3)
throw new Exception("Error: invalid-arity, the substring expects three arguments");
// using .GetTokenType() extension method
// to recognize all "string" types
// (string, guid, date time, timespan, uri, bytes)
if (arguments[0].Token.GetTokenType() != "string")
throw new Exception("Error: invalid-value, the substring function expects its first argument to be a string.");
// using .Type to distinguish integers from floating point values
if (arguments[1].Token.Type != JTokenType.Integer || arguments[2].Token.Type() != JTokenType.Integer)
throw new Exception("Error: invalid-value, the substring function expects its second and third arguments to be integers.");
}
public override JToken Execute(params JmesPathFunctionArgument[] arguments)
{
var text = arguments[0].Token.Value<string>();
var index = arguments[0].Token.Value<int>();
var length = arguments[0].Token.Value<int>();
var sub = text.Substring(index, length);
return new JValue(sub);
}
}
Then, register and use the custom function as you would normally:
using DevLab.JmesPath;
const string input = "{\"foo\": \"bar\"}";
const string expression = "foo.substring(@, 1, 2)";
var jmes = new JmesPath();
jmes.FuntionRepository
.Register<SubstringFunction>()
;
var result = jmes.Transform(input, expression);
System.Diagnostics.Debug.Assert(result == "\"ba\"");