Skip to content

KonnexionsGmbH/jpparse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JPParse

build Hex.pm Coveralls github GitHub GitHub release GitHub Release Date GitHub commits since latest release

Introduction:

Json Path Parser parses a Json path into an abstract syntax tree, ready to be interpreted for matching them to json data objects.

Still missing:

Glossary:

For the path expression:

Property
key/attribute of a json object
Value
Whatever data is associated with a property in a json object
':'
Columns are used to access properties of objects (if an object has multiple identical properties, only the last one will match).
'[ ]'
Square brackets signify you expect the data to be a list, and you wish to traverse it.
They can contain:
  • no value: meaning you wish to traverse the whole list.
  • a number: meaning you wish to only access the data on that index of the list
  • a range (ex. 1-45): meaning you wish to traverse a sublist
  • multiple numbers (ex 1,2,5): meaning you wish to access the data only on those index numbers
'{ }'
Curly braces signify you expect the data to be an object, and you wish to somehow traverse it
They can contain:
  • no value: meaning you wish to traverse every value of the whole object
  • a property: meaning you wish to access the value of that property (same as using a column). Only the last corresponding property will match.
  • multiple properties: meaning you wish to access the values of those properties
'$keys$'
Signifies you wish to work on (or return) the object keys as if they were a list (containing the object's keys). Is understood as being a property.
'$values$'
Signifies you wish to work on (or return) the object values as if they were a list (containing the object's values). Is understood as being a property.
'$firstChild$'
Signifies you wish to work on the first value of the object, whatever the key. Is understood as being a property.

"single value / list of values as result" operator correspondence table

From the moment a path expression contains an operator who returns a list, result will be a list, even if only a single object matches.

input output
a:b when b is list List
a:b when b is object Single (object)
a:b when b is neither list or object Single (value)
a[] List
a[1] List
a[1,2] List
b{} List
b{prop} List
b{$keys$} Single (object)

For the parsed form expression:

'_'
When used as second parameter in '{ }' or '[ ]' functions, signifies 'match all' When used as first parameter, signifies 'work on anonymous root data object' (used when the path expression starts with brackets or curly braces, or to access the root object).
'{}'
Binary function. First parameter is the object to work on, second the attribute(s). It's the default operator: `{':', [a]}` is equal in meaning to `{':', [{'{}', '_', a}]}`, and should internally be treated as such.
'[]'
Binary function: First parameter is the list to work on, second the index(es).
'-'
Binary function: First parameter is the position to start from, second the position to stop at.
':'
Unary function: Parameter list contains the path elements to traverse.
'$anything$
Nullary function: translates to whatever the inclosed name may mean (currently supported: `firstChild`, `keys`, `values`)

jpparse grammar/syntax examples:

path expression parsed form
<<"a{}[]">> {'[]',{'{}',<<"a">>,[][]}
<<"a[1,2,3]">> {'[]',<<"a">>,[1,2,3]}
<<"a{x,y,z}">> {'{}',<<"a">>,[<<"x">>,<<"y">>,<<"z">>]}
<<"a:b[]:c">> {':',<<"c">>,{'[]',{':',<<"b">>,<<"a">>[]}}
<<"a:b[1,2,3]">> {'[]',{':',<<"b">>,<<"a">>[1,2,3]}
<<"a:b{x,y,z}">> {'{}',{':',<<"b">>,<<"a">>[<<"x">>,<<"y">>,<<"z">>]}
<<"a[]{}:b{}[]">> {'[]',{'{}',{':',<<"b">>,{'{}',{'[]',<<"a">>,[][]}[][]}
<<"a{$tok$}">> {'{}',<<"a">>,[{'$',<<"tok">>}]}
<<"a:b{$tok$}[1,2]">> {'[]',{'{}',{':',<<"b">>,<<"a">>[{'$',<<"tok">>}][1,2]}
<<"a{f(x)}[f(y)]">> {'[]',{'{}',<<"a">>,[{'fun',<<"f">>,[<<"x">>]}][{'fun',<<"f">>,[<<"y">>]}]}
<<"a:b[f()]:c">> {':',<<"c">>,{'[]',{':',<<"b">>,<<"a">>},[{'fun',<<"f">>,[]}]}}
<<"a:b{f()}:c">> {':',<<"c">>,{'{}',{':',<<"b">>,<<"a">>},[{'fun',<<"f">>,[]}]}}
<<"a:f(y(p,q),x):c">> {':',<<"c">>,{':',{'fun',<<"f">>,[{'fun',<<"y">>,[<<"p">>,<<"q">>]<<"x">>]},<<"a">>}}
<<"a:b[]{f(x:y)}:c">> {':',<<"c">>,{'{}',{'[]',{':',<<"b">>,<<"a">>},[]},[{'fun',<<"f">>,[{':',<<"y">>,<<"x">>}]}]}}

more examples

Example Usage

1> jpparse:parsetree_with_tokens("a:b").
{ok,{{':',<<"b">>,<<"a">>},
     [{'STRING',1,"a"},{':',1},{'STRING',1,"b"}]}}
2> jpparse:parsetree("a:b{1-2"). 
{parse_error,{1,"syntax error before: '-'",
              [{'STRING',1,"a"},
               {':',1},
               {'STRING',1,"b"},
               {'{',1},
               {'STRING',1,"1"},
               {'-',1},
               {'STRING',1,"2"}]}}
3> jpparse:parsetree("a:b[1-2").
{parse_error,{1,"syntax error before: '-'",
              [{'STRING',1,"a"},
               {':',1},
               {'STRING',1,"b"},
               {'[',1},
               {'STRING',1,"1"},
               {'-',1},
               {'STRING',1,"2"}]}}
4> jpparse:parsetree_with_tokens("a:b[1,2]").
{ok,{{'[]',{':',<<"b">>,<<"a">>},[1,2]},
     [{'STRING',1,"a"},
      {':',1},
      {'STRING',1,"b"},
      {'[',1},
      {'STRING',1,"1"},
      {',',1},
      {'STRING',1,"2"},
      {']',1}]}}
5> jpparse:parsetree_with_tokens("a:b{x,y}").
{ok,{{'{}',{':',<<"b">>,<<"a">>},[<<"x">>,<<"y">>]},
     [{'STRING',1,"a"},
      {':',1},
      {'STRING',1,"b"},
      {'{',1},
      {'STRING',1,"x"},
      {',',1},
      {'STRING',1,"y"},
      {'}',1}]}}