masukomi / jsonpath-perl
- Source
- Commits
- Network (1)
- Issues (0)
- Downloads (0)
- Wiki (1)
- Graphs
-
Tree:
3bf117f
tree 8f98f06b05ee90462eb2462ab5f0f72c52831af6
parent 2a23a4c0246828ab1f90362b2b2bc686c33d35f6
| name | age | message | |
|---|---|---|---|
| |
.gitignore | Fri Nov 07 14:06:20 -0800 2008 | |
| |
README.mkdn | ||
| |
bin/ | ||
| |
lib/ | ||
| |
tests/ |
JSONPath (Perl) - XPath for JSON and Perl
JSONPath is the brainchild of Stephan Goessner. It takes the basic concept of XPATH and, using similar syntax, applies it to JSON data structures. This documentation is taken directly from Stephan's JSONPath page with minor tweaks specific to the Perl port. You can find the JavaScript, PHP, and C# implementation of it on the JSONPath page at Google Code.
JSONPath is distributed under the MIT License.
JSONPath expressions
JSONPath expressions always refer to a JSON structure in the same way as XPath expression are used in combination with an XML document. Since a JSON structure is usually anonymous and doesn't necessarily have a "root member object" JSONPath assumes the abstract name $ assigned to the outer level object.
JSONPath expressions can use the dot notation
$.store.book[0].title
or the bracket notation
$['store']['book'][0]['title']
for input pathes. Internal or output pathes will always be converted to the more general bracket notation.
JSONPath allows the wildcard symbol * for member names and array indices. It borrows the descendant operator '..' from E4X and the array slice syntax proposal [start:end:step] from ECMASCRIPT 4.
Expressions of the underlying scripting language () can be used as an alternative to explicit names or indices as in
$.store.book[(@.length-1)].title
using the symbol '@' for the current object. Filter expressions are supported via the syntax ?() as in
$.store.book[?(@.price < 10)].title
Here is a complete overview and a side by side comparison of the JSONPath syntax elements with its XPath counterparts.
| XPath | JSONPath | Result |
/store/book/author | $.store.book[*].author | the authors of all books in the store |
//author | $..author | all authors |
/store/* | $.store.* | all things in store, which are some books and a red bicycle. |
/store//price | $.store..price | the price of everything in the store. |
//book[3] | $..book[2] | the third book |
//book[last()] | $..book[(@.length-1)]$..book[-1:] | the last book in order. |
//book[position()<3] | $..book[0,1]$..book[:2] | the first two books |
//book[isbn] | $..book[?(@.isbn)] | filter all books with isbn number |
//book[price<10] | $..book[?(@.price<10)] | filter all books cheapier than 10 |
//* | $..* | all Elements in XML document. All members of JSON structure. |
??? | $.store.! | all the keys in the store hash (bicycle, book) |
XPath has a lot more to offer (Location pathes in not abbreviated syntax, operators and functions) than listed here. Moreover there is a remarkable difference how the subscript operator works in Xpath and JSONPath.
* Square brackets in XPath expressions always operate on the node set resulting from the previous path fragment. Indices always start by 1.
* With JSONPath square brackets operate on the object or array addressed by the previous path fragment. Indices always start by 0.
[edit] [comment] [remove] |2007-08-18| e3 # JSONPath examples
Let's practice JSONPath expressions by some more examples. We start with a simple JSON structure built after an XML example representing a bookstore (original XML file).
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
| XPath | JSONPath | Result |
/store/book/author | $.store.book[*].author | the authors of all books in the store |
//author | $..author | all authors |
/store/* | $.store.* | all things in store, which are some books and a red bicycle. |
/store//price | $.store..price | the price of everything in the store. |
//book[3] | $..book[2] | the third book |
//book[last()] | $..book[(@.length-1)]$..book[-1:] | the last book in order. |
//book[position()<3] | $..book[0,1]$..book[:2] | the first two books |
//book[isbn] | $..book[?(@.isbn)] | filter all books with isbn number |
//book[price<10] | $..book[?(@.price<10)] | filter all books cheapier than 10 |
//* | $..* | all Elements in XML document. All members of JSON structure. |
??? | $.store.! | all the keys in the store hash (bicycle, book) |
JSONPath implementation
JSONPath.pm is a simple perl class, ported from the Javascript and PHP versions, that can be wrapped within a script like jsonpath.pl to give command line inspection into a JSON file or leveraged in a larger application. To use it simply parse the JSON with your favorite JSON library, create an instance of JSONPath, and pass the parsed json to it's run method along with your JSONPath expression
use JSON;
my $json_structure = from_json($raw_json);
my $jp = JSONPath->new();
my $raw_result = $jp->run($json_structure, "$..author"); # either a data structure or zero
print to_json($raw_result, {utf8 => 1, pretty => 1}) . "\n";
The run method also takes an optional third argument, a hash with any options. Currently the only supported option is "result_type" which can be "VALUE" or "PATH".
the example results in the following arrays:
res1:
[ "Nigel Rees",
"Evelyn Waugh",
"Herman Melville",
"J. R. R. Tolkien"
]
res2:
[ "$['store']['book'][0]['author']",
"$['store']['book'][1]['author']",
"$['store']['book'][2]['author']",
"$['store']['book'][3]['author']"
]
Please note, that the return value of jsonPath is an array, which is also a valid JSON structure. So you might want to apply jsonPath to the resulting structure again or use one of your favorite array methods as sort with it.
Issues
- Currently only single quotes allowed inside of JSONPath expressions.
- Script expressions inside of JSONPath locations are currently not recursively evaluated by jsonPath. Only the global $ and local @ symbols are expanded by a simple regular expression.
- An alternative for jsonPath to return false in case of no match may be to return an empty array in future.

