5. Dezember 2016

JsonPath

Any time a piece of my software receives a JSON message it must dive into the JSON and extract parameters. Sometimes the JSON is deeply nested and parameters are buried inside arrays of objects of arrays.

I want to access these parameters quickly without dissecting the JSON by looping and if-ing through the layers. In other words: I want single line expressions to dive into JSON and extract values.

You can call it XPath for JSON, but in a language integrated and compiled way, which is much faster, than XPath and supported by Intellisense (autocomplete).

GitHub project: https://github.com/wolfspelz/JsonPath
NuGet package: https://www.nuget.org/packages/JsonPath

Example: extract the 42 from:

var data = "[ '1st', '2nd', { 'aString': 'Hello World', 'aNumber': 42 } ]"

... parse it:

var json = new Node(data);

... extract it:

int fourtytwo = json[2]["aNumber"];

Invalid keys do not throw exceptions. They return 0 (zero), "" (empty string), or empty list:

int zero = json[1000]["noNumber"];

Of course, you can foreach a dictionary (aka JS object):

foreach (var pair in json[2]) {}

And iterate over a list (aka JS array):

for (int i = 0; i < json.Count; i++) {
    string value = json[i];
}

You can even LINQ it:

json[2].Where(pair => pair.Key == "aNumber").First().Value

and:

(from x in json[2] where x.Key == "aNumber" select x.Value).First()

Now get me the 50 from this JSON:

var data = "[ { 
        aInt: 41, 
        bLong: 42000000000, 
        cBool: true, 
        dString: '43', 
        eFloat: 3.14159265358979323 
    }, { 
        fInt: 44, 
        gLong: 45000000000, 
        hString: "46"
    }, { 
        iList: [ 
            { jInt: 47, kString: '48' }, 
            { lInt: 49, mString: '50' }
        ], 
    }
]";

I can do it in a single line, no foreach no if:

var fifty = json[2]["iList"][1]["mString"];

Other people had the same idea years ago: http://goessner.net/articles/JsonPath/. But there does not seem to be a C#/.NET implementation yet. So here it is: GitHub, nuget.

_happy_jsoning()