2017 © Pedro Peláez
 

library jsonpath

JSONPath implementation for querying and updating JSON objects

image

skyscanner/jsonpath

JSONPath implementation for querying and updating JSON objects

  • Wednesday, September 13, 2017
  • by motanelu
  • Repository
  • 12 Watchers
  • 57 Stars
  • 95,684 Installations
  • PHP
  • 2 Dependents
  • 0 Suggesters
  • 13 Forks
  • 0 Open issues
  • 11 Versions
  • 23 % Grown

The README.md

JsonPath

Build Status Latest Stable Version License, (*1)

This is a JSONPath implementation for PHP., (*2)

This implementation features all elements in the specification except the () operator (in the spcecification there is the $..a[(@.length-1)], but this can be achieved with $..a[-1] and the latter is simpler)., (*3)

In case of no matches for the query it will return an empty array., (*4)

Features

This implementation has the following features: * Regex match key (p.e. $.*[?(/^bo{2}k$/)] or $[?(/a\wthors/)]). * Regex match value comparisons (p.e. $.store.book[?(@.author =~ /.*Tolkien/)]) * For the child operator [] there is no need to surround child names with quotes (p.e. $[store][book, bicycle]) except if the name of the field is a non-valid javascript variable name. * .length can be used to get the length of a string, get the length of an array and to check if a node has children. * The in operator allows filtering for a value in a specified list: $..[?(@.author in ["Nigel Rees", "Evelyn Waugh", $.store.book[3].author])] * Object oriented implementation. * Get, set and add operations. * Magic methods implemented: * __get: $obj->{'$...'}. * __set: $obj->{'$...'} = $val. * __toString: echo $obj prints the json representation of the JsonObject. * Not using eval()., (*5)

Installation

To install JsonPath you will need to be using Composer in your project. To install it please see the docs., (*6)

composer require galbar/jsonpath

Usage

In every file you use it add:, (*7)

use JsonPath\JsonObject;

Now you can create an instance of JsonObject and use it:, (*8)

// $json can be a string containing json, a PHP array, a PHP object or null.
// If $json is null (or not present) the JsonObject will be empty.
$jsonObject = new JsonObject();
// or
$jsonObject = new JsonObject($json);

// get
$obj->get($jsonPath);
$obj->{'$.json.path'};

// set
$obj->set($jsonPath, $value);
$obj->{'$.json.path'} = $value;

// get the json representation
$obj->getJson();
$str = (string)$obj;
echo $obj;

// get the PHP array representation
$obj->getValue();

// add values
$obj->add($jsonPath, $value[, $field]);

// remove values
$obj->remove($jsonPath, $field);

SmartGet

When creating a new instance of JsonObject, you can pass a second parameter to the constructor. This sets the behaviour of the instance to use SmartGet., (*9)

What SmartGet does is to determine if the given JsonPath branches at some point, if it does it behaves as usual; otherwise, it will directly return the value pointed by the given path (not the array containing it) or false if not found., (*10)

GetJsonObjects

Sometimes you need to access multiple values of a subobject that has a long prefix (p.e. $.a.very.long.prefix.for.[*].object), in this case you would first get said object and make a JsonObject of it and then access its properties., (*11)

Now if you want to edit the object (set or add values) and want these changes to affect the original object, the way of doing this is by using JsonObject::getJsonObjects($jsonpath). This method works the same way get does, but it will return the results as JsonObject instances containing a reference to the value in the source JsonObject., (*12)

JsonPath Language

This library implements the following specification:, (*13)

var_name¹   = /^\.([\p{L}\p{N}\_\$][\p{L}\p{N}\_\-\$]*|\*)(.*)/u
number      = ([0-9]+(\.[0-9]*) | ([0-9]*\.[0-9]+))
string      = ('\''.*?'\'' | '"'.*?'"')
boolean     = ('true' | 'false')
regpattern  = '/'.*?'/i?x?'
null        = 'null'
index       = -?[0-9]+

jsonpath    = '$' operator*
childpath   = '@' operator*

operator    = (childname | childfilter | recursive) operator*

childname   = '.' (var_name | '*')
childfilter = '[' ('*' | namelist | indexlist | arrayslice | filterexpr) ']'
recursive   = '..' (var_name | childfilter | '*')

namelist    = var_name (',' (var_name | '\'' .*? '\'' | '"' .*? '"'))*
indexlist   = index (',' index)*
arrayslice  = index? ':' index? ':' index?
filterexpr  = '?(' ors ' | regpattern)'

ors         = ands (' ' ( 'or' | '\|\|' ) ' ' ands)*
ands        = expr (' ' ( 'and' | '&&' ) ' ' expr)*
expr        = ( 'not ' | '! ' )? (value | comp | in_array)
comp        = value ('==' | '!=' | '<' | '>' | '<=' | '>=' | '=~') value
value       = (jsonpath | childpath | number | string | boolean | regpattern | null | length)
length      = (jsonpath | childpath) '.length'
in_array    = value 'in' '[' value (',' value)* ']'

¹var_name: the regex roughly translates to "any valid JavaScript variable name", plus some quirks such as names starting with numbers or containing dashes (-)., (*14)

Limitations on the specification:

  • The jsonpath inside value cannot contain or, and or any comparator.
  • Jsonpaths in value return the first element of the set or false if no result.
  • Boolean operations can't be grouped with parethesis.
  • ands are run before ors. That means that a and 1 = b or c != d is the same as (a and 1) or (c != d)

The .length operator can be used to: * Get the number of childs a node in the JsonObject has: $..*[?(@.length > 3)] * Filter for nodes that have childs: $..*[?(@.length)] * Or filter for nodes that don't have childs (leaves): $..*[?(not @.length)] * Check the length of a string: $.path.to[?(@.a.string.length > 10)] * Get the length of a string: $.path.to.field.length * Get the length of an array: $.path.to.array.length * Get the length of each array inside an array of arrays: $.path.to.array[*].array[*].length * Get the length of each string inside an array of strings: $.path.to.array[*].array[*].key.length, (*15)

The comparators:
==, !=, <, >, <=, >= do what expected (compare by type and value).
=~ is a regex comparator, matches the left operand with the pattern in the right operand. The value on the left must be a string and on the right regpattern. Other wise returns false., (*16)

JsonPath Example

Consider the following json:, (*17)

{ "store": {
    "book": [
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95,
        "available": true
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99,
        "available": false
      },
      { "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99,
        "available": true
      },
      { "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99,
        "available": false
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95,
      "available": true
    }
  },
  "authors": [
    "Nigel Rees",
    "Evelyn Waugh",
    "Herman Melville",
    "J. R. R. Tolkien"
  ]
}
JsonPath Result
$.store.bicycle.price The price of the bicycle.
$.store.book[*] All books.
$.store.book[1,3] The second and fourth book.
$.store.book[1:3] From the second book to the third.
$.store.book[:3] From the first book to the third.
$.store.book[x:y:z] Books from x to y with a step of z.
$..book[?(@.category == 'fiction')] All books with category == 'fiction'.
$..*[?(@.available == true)].price All prices of available products.
$..book[?(@.price < 10)].title The title of all books with price lower than 10.
$..book[?(@.author==$.authors[3])] All books by "J. R. R. Tolkien"
$[store] The store.
$['store'] The store.
$..book[*][title, 'category', "author"] title, category and author of all books.
$..book[?(@.author in [$.authors[0], $.authors[2]])] All books by "Nigel Rees" or "Herman Melville".
$.store.book[?(@.category == 'fiction' and @.price < 10 or @.color == "red")].price Books of fiction with a price lower than 10 or something with of color red. (and takes precedence to or)

See more examples in the ./tests/Galbar/JsonPath folder., (*18)

Test

To run tests, from the project root folder:
php app/test.php <jsonpath> [<file to json file>], (*19)

If no json file is given it defaults to the json object described previously in this file., (*20)

For example:
php app/test.php "$..*[?(@.category == 'fiction' and @.price < 10 or @.color == \"red\")].price"
Result should be:
[19.95,8.99], (*21)

Ready to code

you can open the project in your browser and can start coding Gitpod ready-to-code, (*22)

Docs

To generate the docs, from the project root folder:
php vendor/bin/sami.php update app/docgen.php, (*23)

The Versions

13/09 2017

dev-master

9999999-dev

JSONPath implementation for querying and updating JSON objects

  Sources   Download

Apache 2.0

The Requires

  • php >=5.4

 

The Development Requires

by Alessio Linares
by Tudor Barbu

json path jsonpath

13/09 2017

1.0

1.0.0.0

JSONPath implementation for querying and updating JSON objects

  Sources   Download

Apache 2.0

The Requires

  • php >=5.4

 

The Development Requires

by Alessio Linares

json path jsonpath

04/09 2017

dev-drop_php53

dev-drop_php53

JSONPath implementation for querying and updating JSON objects

  Sources   Download

Apache 2.0

The Requires

  • php >=5.4

 

The Development Requires

by Alessio Linares

json path jsonpath

07/08 2017

0.8

0.8.0.0

JSONPath implementation for querying and updating JSON objects

  Sources   Download

Apache 2.0

The Requires

  • php >=5.3.3

 

The Development Requires

by Alessio Linares

json path jsonpath

02/12 2016

0.7.3

0.7.3.0

JSONPath implementation for querying and updating JSON objects

  Sources   Download

Apache 2.0

The Requires

  • php >=5.3.3

 

The Development Requires

by Alessio Linares
by Tudor Barbu

json path jsonpath

28/11 2016

0.7.2

0.7.2.0

JSONPath implementation for querying and updating JSON objects

  Sources   Download

Apache 2.0

The Requires

  • php >=5.3.3

 

The Development Requires

by Alessio Linares
by Tudor Barbu

json path jsonpath

20/10 2015

0.7.1

0.7.1.0

JSONPath implementation for querying and updating JSON objects

  Sources   Download

Apache 2.0

The Requires

  • php >=5.3.3

 

The Development Requires

by Alessio Linares
by Tudor Barbu

json path jsonpath

21/09 2015

0.7.0

0.7.0.0

JSONPath implementation for querying and updating JSON objects

  Sources   Download

Apache 2.0

The Requires

  • php >=5.3.3

 

The Development Requires

by Alessio Linares
by Tudor Barbu

json path jsonpath

17/09 2015

0.6.0

0.6.0.0

JSONPath implementation for querying and updating JSON objects

  Sources   Download

Apache 2.0

The Requires

  • php >=5.3.3

 

The Development Requires

by Alessio Linares
by Tudor Barbu

json path jsonpath

16/09 2015

0.5.1

0.5.1.0

JSONPath implementation for querying and updating JSON arrays

  Sources   Download

Apache 2.0

The Requires

  • php >=5.3.3

 

The Development Requires

by Alessio Linares
by Tudor Barbu

json path jsonpath

16/09 2015

0.5.0

0.5.0.0

  Sources   Download

Apache 2.0

The Requires

  • php >=5.3.3

 

The Development Requires

by Alessio Linares
by Tudor Barbu

json path jsonpath