Windows paths in json

JSONPath and Query JSON using JSONPath

JSONPath and Query JSON using JSONPath

One of the most important advantage of JSON is that it is a light weight format that can be used to interchange data between computers and processes. JSON , like XML, is a format to provide structure to the data. If you are not familiar with JSON, please go through this tutorial first of Introduction to JSON .

In this tutorial, we will learn more about JSONPath and Query JSON using JSONPath. We will be covering the following topic:

  • What is JSONPath?
  • How to Query JSON with JSONPath?
  • Different strategies to query JSON object and JSON Array.

What is JSONPath?

Every JSON object is composed on an inherent hierarchy and structure. Every JSON ends up creating a tree of nodes, where each node is a JSON Element . Let us take an example here, below is a simple JSON expressing a collection of countries

At the top most level we have a Root node, which is basically the node containing all of the current JSON. Inside this root node, we have following nodes

  • Description
  • Region
  • Countries

Description and Region are simple leaf nodes in the tree. But Countries is a non-leaf node, which further contains more nodes. Here Countries node contains an array of two countries. If we were to simply define a hierarchical relation between the Root node and any node in the JSON we can do like shown below.

Note: Let us represent Root node by $ and a relationship from parent to child with >>

Description node will be represented by $ >> Description .

Region node will be represented by $ >> Region .

Similarly, we can also define a relationship between the Root node and the zero’th item in the Countries array. Relationship will be $ >> Countries[0] where [ ] is the index operator to represent an item at n index in an Array of Countries.

In a way this hierarchy in JSON allows us to create a standard mechanism to traverse through specific parts of the JSON. A standard way to do this is called JSONPath .

How to Query JSON using JSONPath?

JSONPath creates a uniform standard and syntax to define different parts of a JSON document. JSONPath defines expressions to traverse through a JSON document to reach to a subset of the JSON. This topic is best understood by seeing it in action. We have created a web page which can help you evaluate a JSONPath. Use this page to practice writing JSONPath. This is the link to JSONPath evaluator.

Get Root node operator in JsonPath

Root node operator in JSON is represented by a $ sign. $ will return all the nodes inside the JSON document. To try this out open the JSONPath evaluator page and type $ in the JSONPath field. As shown in the image below

Get Children operator in JSONPath

In order to get children of a given node, we can use the Dot (.) operator or the [‘childname’] operator. In order to get all the Countries we can have JSONPath as

JSON with JSONPath

One of the biggest strengths of XML is XPath, the query-oriented language to query subsections of an XML document. In the same line, JSONPath is a query language for JSON with features similar to XPath. JSONPath is used for selecting and extracting a JSON document’s property values.

To use JSONPath, we will need to include its dependency and then use it.

JSONPath Syntax

A JsonPath expression begins with the dollar sign ( $ ) character, which refers to the root element of a query. The dollar sign is followed by a sequence of child elements, which are separated via dot (code) notation or via the square brackets (code).

The important JSONPath syntax rules are:

  • $ symbol refers to the root object or element.
  • @ symbol refers to the current object or element.
  • . operator is the dot-child operator, which you use to denote a child element of the current element.
  • [ ] is the subscript operator, which you use to denote a child element of the current element (by name or index).
  • * operator is a wildcard, returning all objects or elements regardless of their names.
  • , operator is the union operator, which returns the union of the children or indexes indicated.
  • : operator is the array slice operator, so you can slice collections using the syntax [start:end:step] to return a subcollection of a collection.
  • ( ) operator lets you pass a script expression in the underlying implementation’s script language. It’s not supported by every implementation of JSONPath, however.
  • ? ( ) to query all items that meet a certain criteria.
Читайте также:  Как пользоваться терминалом windows

Example: JSONPath Expressions

JSONPath Example

We have the following JSON document. We will apply the JSONPath expressions on it.

Example 1

Using JSONPath to find the names of all authors.

Example 2

Using JSONPath to find the details for book number 4. The array index is zero-based.

How to use C# example using JsonPath?

I’m trying to use JsonPath for .NET (http://code.google.com/p/jsonpath/downloads/list) and I’m having trouble finding an example of how to parse a Json string and a JsonPath string and get a result.

Has anyone used this?

3 Answers 3

The problem you are experiencing is that the C# version of JsonPath does not include a Json parser so you have to use it with another Json framework that handles serialization and deserialization.

The way JsonPath works is to use an interface called IJsonPathValueSystem to traverse parsed Json objects. JsonPath comes with a built-in BasicValueSystem that uses the IDictionary interface to represent Json objects and the IList interface to represent Json arrays.

You can create your own BasicValueSystem -compatible Json objects by constructing them using C# collection initializers but this is not of much use when your Json is coming in in the form of strings from a remote server, for example.

So if only you could take a Json string and parse it into a nested structure of IDictionary objects, IList arrays, and primitive values, you could then use JsonPath to filter it! As luck would have it, we can use Json.NET which has good serialization and deserialization capabilities to do that part of the job.

Unfortunately, Json.NET does not deserialize Json strings into a format compatible with the BasicValueSystem . So the first task for using JsonPath with Json.NET is to write a JsonNetValueSystem that implements IJsonPathValueSystem and that understands the JObject objects, JArray arrays, and JValue values that JObject.Parse produces.

So download both JsonPath and Json.NET and put them into a C# project. Then add this class to that project:

Now with all three of these pieces we can write a sample JsonPath program:

which produces this output:

This example is based on the Javascript sample at the JsonPath site:

Windows paths in json

JSONPath Plus

Analyse, transform, and selectively extract data from JSON documents (and JavaScript objects).

jsonpath-plus expands on the original specification to add some additional operators and makes explicit some behaviors the original did not spell out.

  • Compliant with the original jsonpath spec
  • Convenient additions or elaborations not provided in the original spec:
    • ^ for grabbing the parent of a matching item

    for grabbing property names of matching items (as array)

  • Type selectors for obtaining:
    • Basic JSON types: @null() , @boolean() , @number() , @string() , @array() , @object()
    • @integer()
    • The compound type @scalar() (which also accepts undefined and non-finite numbers when querying JavaScript objects as well as all of the basic non-object/non-function types)
    • @other() usable in conjunction with a user-defined otherTypeCallback
    • Non-JSON types that can nevertheless be used when querying non-JSON JavaScript objects ( @undefined() , @function() , @nonFinite() )
  • @path / @parent / @property / @parentProperty / @root shorthand selectors within filters
  • Escaping
    • ` for escaping remaining sequence
    • @[‘. ‘] / ?@[‘. ‘] syntax for escaping special characters within property names in filters
  • Documents $.. (getting all parent components)
  • ESM and UMD export formats
  • In addition to queried values, can return various meta-information including paths or pointers to the value, as well as the parent object and parent property name (to allow for modification).
  • Utilities for converting between paths, arrays, and pointers
  • Option to prevent evaluations permitted in the original spec or supply a sandbox for evaluated values.
  • Option for callback to handle results as they are obtained.
  • jsonpath-plus is consistently performant with both large and small datasets compared to other json querying libraries per json-querying-performance-testing. You can verify these findings by running the project yourself and adding more perf cases.

    For browser usage you can directly include dist/index-browser-umd.js ; no Browserify magic is necessary:

    ESM (Modern browsers)

    You may also use ES6 Module imports (for modern browsers):

    Or if you are bundling your JavaScript (e.g., with Rollup), just use, noting that mainFields should include browser for browser builds (for Node, the default, which checks module , should be fine):

    The full signature available is:

    The arguments path , json , callback , and otherTypeCallback can alternatively be expressed (along with any other of the available properties) on options .

    Note that result will contain all items found (optionally wrapped into an array) whereas callback can be used if you wish to perform some operation as each item is discovered, with the callback function being executed 0 to N times depending on the number of independent items to be found in the result. See the docs below for more on JSONPath ‘s available arguments.

    The properties that can be supplied on the options object or evaluate method (as the first argument) include:

    • path (required) — The JSONPath expression as a (normalized or unnormalized) string or array
    • json (required) — The JSON object to evaluate (whether of null, boolean, number, string, object, or array type).
    • autostart (default: true) — If this is supplied as false , one may call the evaluate method manually.
    • flatten (default: false) — Whether the returned array of results will be flattened to a single dimension array.
    • resultType (default: «value») — Can be case-insensitive form of «value», «path», «pointer», «parent», or «parentProperty» to determine respectively whether to return results as the values of the found items, as their absolute paths, as JSON Pointers to the absolute paths, as their parent objects, or as their parent’s property name. If set to «all», all of these types will be returned on an object with the type as key name.
    • sandbox (default: <>) — Key-value map of variables to be available to code evaluations such as filtering expressions. (Note that the current path and value will also be available to those expressions; see the Syntax section for details.)
    • wrap (default: true) — Whether or not to wrap the results in an array. If wrap is set to false , and no results are found, undefined will be returned (as opposed to an empty array when wrap is set to true). If wrap is set to false and a single non-array result is found, that result will be the only item returned (not within an array). An array will still be returned if multiple results are found, however. To avoid ambiguities (in the case where it is necessary to distinguish between a result which is a failure and one which is an empty array), it is recommended to switch the default to false .
    • preventEval (default: false) — Although JavaScript evaluation expressions are allowed by default, for security reasons (if one is operating on untrusted user input, for example), one may wish to set this option to true to throw exceptions when these expressions are attempted.
    • parent (default: null) — In the event that a query could be made to return the root node, this allows the parent of that root node to be returned within results.
    • parentProperty (default: null) — In the event that a query could be made to return the root node, this allows the parentProperty of that root node to be returned within results.
    • callback (default: (none)) — If supplied, a callback will be called immediately upon retrieval of an end point value. The three arguments supplied will be the value of the payload (according to resultType ), the type of the payload (whether it is a normal «value» or a «property» name), and a full payload object (with all resultType s).
    • otherTypeCallback (default: when @other() is encountered>) — In the current absence of JSON Schema support, one can determine types beyond the built-in types by adding the operator @other() at the end of one’s query. If such a path is encountered, the otherTypeCallback will be invoked with the value of the item, its path, its parent, and its parent’s property name, and it should return a boolean indicating whether the supplied value belongs to the «other» type or not (or it may handle transformations and return false).
    • evaluate(path, json, callback, otherTypeCallback) OR evaluate(

    , json: , callback:, otherTypeCallback:>) — This method is only necessary if the autostart property is set to false . It can be used for repeated evaluations using the same configuration. Besides the listed properties, the latter method pattern can accept any of the other allowed instance properties (except for autostart which would have no relevance here).

    Class properties and methods

    • JSONPath.cache — Exposes the cache object for those who wish to preserve and reuse it for optimization purposes.
    • JSONPath.toPathArray(pathAsString) — Accepts a normalized or unnormalized path as string and converts to an array: for example, [‘$’, ‘aProperty’, ‘anotherProperty’] .
    • JSONPath.toPathString(pathAsArray) — Accepts a path array and converts to a normalized path string. The string will be in a form like: $[‘aProperty’][‘anotherProperty][0] . The JSONPath terminal constructions

    and ^ and type operators like @string() are silently stripped.
    JSONPath.toPointer(pathAsArray) — Accepts a path array and converts to a JSON Pointer. The string will be in a form like: /aProperty/anotherProperty/0 (with any

    and / internal characters escaped as per the JSON Pointer spec). The JSONPath terminal constructions

    and ^ and type operators like @string() are silently stripped.

    Syntax through examples

    and the following XML representation:

    Please note that the XPath examples below do not distinguish between retrieving elements and their text content (except where useful for comparisons or to prevent ambiguity). Note: to test the XPath examples (including 2.0 ones), this demo may be helpful (set to xml or xml-strict ).

    XPath JSONPath Result Notes
    /store/book/author $.store.book[*].author The authors of all books in the store Can also be represented without the $. as store.book[*].author (though this is not present in the original spec); note that some character literals ( $ and @ ) require escaping, however
    //author $..author All authors
    /store/* $.store.* All things in store, which are its books (a book array) and a red bicycle (a bicycle object).
    /store//price $.store..price The price of everything in the store.
    //book[3] $..book[2] The third book (book object)
    //book[last()] $..book[(@.length-1)]
    $..book[-1:]
    The last book in order. To access a property with a special character, utilize [(@[‘. ‘])] for the filter (this particular feature is not present in the original spec)
    //book[position() [?@[‘. ‘]] for the filter (this particular feature is not present in the original spec)
    //book[price @ allowing filtering objects by property value (not necessarily within arrays), you can add ^ after the expression to get at the object possessing the filtered properties
    / $ The root of the JSON object (i.e., the whole object itself) To get a literal $ (by itself or anywhere in the path), you must use the backtick escape
    //*/*|//*/*/text() $..* All Elements (and text) beneath root in an XML document. All members of a JSON structure beneath the root.
    //* $.. All Elements in an XML document. All parent components of a JSON structure including root. This behavior was not directly specified in the original spec
    //*[price>19]/.. $..[?(@.price>19)]^ Parent of those specific items with a price greater than 19 (i.e., the store value as the parent of the bicycle and the book array as parent of an individual book) Parent (caret) not present in the original spec
    /store/*/name() (in XPath 2.0) $.store.*

    The property names of the store sub-object («book» and «bicycle»). Useful with wildcard properties. Property name (tilde) is not present in the original spec
    /store/book[not(. is /store/book[1])] (in XPath 2.0) $.store.book[?(@path !== «$[‘store’][‘book’][0]»)] All books besides that at the path pointing to the first @path not present in the original spec
    //book[parent::*/bicycle/color = «red»]/category $..book[?(@parent.bicycle && @parent.bicycle.color === «red»)].category Grabs all categories of books where the parent object of the book has a bicycle child whose color is red (i.e., all the books) @parent is not present in the original spec
    //book/*[name() != ‘category’] $..book.*[?(@property !== «category»)] Grabs all children of «book» except for «category» ones @property is not present in the original spec
    //book[position() != 1] $..book[?(@property !== 0)] Grabs all books whose property (which, being that we are reaching inside an array, is the numeric index) is not 0 @property is not present in the original spec
    /store/*/*[name(parent::*) != ‘book’] $.store.*[?(@parentProperty !== «book»)] Grabs the grandchildren of store whose parent property is not book (i.e., bicycle’s children, «color» and «price») @parentProperty is not present in the original spec
    //book[count(preceding-sibling::*) != 0]/*/text() $..book.*[?(@parentProperty !== 0)] Get the property values of all book instances whereby the parent property of these values (i.e., the array index holding the book item parent object) is not 0 @parentProperty is not present in the original spec
    //book[price = /store/book[3]/price] $..book[?(@.price === @root.store.book[2].price)] Filter all books whose price equals the price of the third book @root is not present in the original spec
    //book/../*[. instance of element(*, xs:decimal)] (in XPath 2.0) $..book..*@number() Get the numeric values within the book array @number(), the other basic types (@boolean(), @string()), other low-level derived types (@null(), @object(), @array()), the JSONSchema-added type, @integer(), the compound type @scalar() (which also accepts undefined and non-finite numbers for JavaScript objects as well as all of the basic non-object/non-function types), the type, @other(), to be used in conjunction with a user-defined callback (see otherTypeCallback ) and the following non-JSON types that can nevertheless be used with JSONPath when querying non-JSON JavaScript objects (@undefined(), @function(), @nonFinite()) are not present in the original spec
    //book/*[name() = ‘category’ and matches(., ‘tion$’)] (XPath 2.0) $..book.*[?(@property === «category» && @.match(/TION$/i))] All categories of books which match the regex (end in ‘TION’ case insensitive) @property is not present in the original spec.
    //book/[matches(name(), ‘bn$’)]/parent:: (XPath 2.0) $..book.*[?(@property.match(/bn$/i))]^ All books which have a property matching the regex (end in ‘TION’ case insensitive) @property is not present in the original spec. Note: Uses the parent selector ^ at the end of the expression to return to the parent object; without the parent selector, it matches the two isbn key values.
    ` (e.g., `$ to match a property literally named $ ) Escapes the entire sequence following (to be treated as a literal) ` is not present in the original spec; to get a literal backtick, use an additional backtick to escape

    Any additional variables supplied as properties on the optional «sandbox» object option are also available to (parenthetical-based) evaluations.

    Potential sources of confusion for XPath users

    Оцените статью