Python JSONPath Next-Generation |Build Status| |PyPI|
=====================================================
A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic
and binary comparison operators, as defined in the original `JSONPath proposal`_.
This packages merges both `jsonpath-rw`_ and `jsonpath-rw-ext`_ and
provides several AST API enhancements, such as the ability to update or remove nodes in the tree.
About
-----
This library provides a robust and significantly extended implementation
of JSONPath for Python. It is tested with CPython 3.8 and higher.
This library differs from other JSONPath implementations in that it is a
full *language* implementation, meaning the JSONPath expressions are
first class objects, easy to analyze, transform, parse, print, and
extend.
Quick Start
-----------
To install, use pip:
.. code:: bash
$ pip install --upgrade jsonpath-ng
Usage
-----
Basic examples:
.. code:: python
$ python
>>> from jsonpath_ng import jsonpath, parse
# A robust parser, not just a regex. (Makes powerful extensions possible; see below)
>>> jsonpath_expr = parse('foo[*].baz')
# Extracting values is easy
>>> [match.value for match in jsonpath_expr.find({'foo': [{'baz': 1}, {'baz': 2}]})]
[1, 2]
# Matches remember where they came from
>>> [str(match.full_path) for match in jsonpath_expr.find({'foo': [{'baz': 1}, {'baz': 2}]})]
['foo.[0].baz', 'foo.[1].baz']
# Modifying values matching the path
>>> jsonpath_expr.update( {'foo': [{'baz': 1}, {'baz': 2}]}, 3)
{'foo': [{'baz': 3}, {'baz': 3}]}
# Modifying one of the values matching the path
>>> matches = jsonpath_expr.find({'foo': [{'baz': 1}, {'baz': 2}]})
>>> matches[0].full_path.update( {'foo': [{'baz': 1}, {'baz': 2}]}, 3)
{'foo': [{'baz': 3}, {'baz': 2}]}
# Removing all values matching a path
>>> jsonpath_expr.filter(lambda d: True, {'foo': [{'baz': 1}, {'baz': 2}]})
{'foo': [{}, {}]}
# Removing values containing particular data matching path
>>> jsonpath_expr.filter(lambda d: d == 2, {'foo': [{'baz': 1}, {'baz': 2}]})
{'foo': [{'baz': 1}, {}]}
# And this can be useful for automatically providing ids for bits of data that do not have them (currently a global switch)
>>> jsonpath.auto_id_field = 'id'
>>> [match.value for match in parse('foo[*].id').find({'foo': [{'id': 'bizzle'}, {'baz': 3}]})]
['foo.bizzle', 'foo.[1]']
# A handy extension: named operators like `parent`
>>> [match.value for match in parse('a.*.b.`parent`.c').find({'a': {'x': {'b': 1, 'c': 'number one'}, 'y': {'b': 2, 'c': 'number two'}}})]
['number two', 'number one']
# You can also build expressions directly quite easily
>>> from jsonpath_ng.jsonpath import Fields
>>> from jsonpath_ng.jsonpath import Slice
>>> jsonpath_expr_direct = Fields('foo').child(Slice('*')).child(Fields('baz')) # This is equivalent
Using the extended parser:
.. code:: python
$ python
>>> from jsonpath_ng.ext import parse
# A robust parser, not just a regex. (Makes powerful extensions possible; see below)
>>> jsonpath_expr = parse('foo[*].baz')
JSONPath Syntax
---------------
The JSONPath syntax supported by this library includes some additional
features and omits some problematic features (those that make it
unportable). In particular, some new operators such as ``|`` and
``where`` are available, and parentheses are used for grouping not for
callbacks into Python, since with these changes the language is not
trivially associative. Also, fields may be quoted whether or not they
are contained in brackets.
Atomic expressions:
+-----------------------+---------------------------------------------------------------------------------------------+
| Syntax | Meaning |
+=======================+=============================================================================================+
| ``$`` | The root object |
+-----------------------+---------------------------------------------------------------------------------------------+
| ```this``` | The "current" object. |
+-----------------------+---------------------------------------------------------------------------------------------+
| ```foo``` | More generally, this syntax allows "named operators" to extend JSONPath is arbitrary ways |
+-----------------------+---------------------------------------------------------------------------------------------+
| *field* | Specified field(s), described below |
+-----------------------+---------------------------------------------------------------------------------------------+
| ``[`` *field* ``]`` | Same as *field* |
+-----------------------+---------------------------------------------------------------------------------------------+
| ``[`` *idx* ``]`` | Array access, described below (this is always unambiguous with field access) |
+-----------------------+---------------------------------------------------------------------------------------------+
Jsonpath operators:
+--------------------------------------+-----------------------------------------------------------------------------------+
| Syntax | Meaning |
+======================================+===================================================================================+
| *jsonpath1* ``.`` *jsonpath2* | All nodes matched by *jsonpath2* starting at any node matching *jsonpath1* |
+--------------------------------------+-----------------------------------------------------------------------------------+
| *jsonpath* ``[`` *whatever* ``]`` | Same as *jsonpath*\ ``.``\ *whatever* |
+--------------------------------------+-----------------------------------------------------------------------------------+
| *jsonpath1* ``..`` *jsonpath2* | All nodes matched by *jsonpath2* that descend from any node matching *jsonpath1* |
+--------------------------------------+-----------------------------------------------------------------------------------+
| *jsonpath1* ``where`` *jsonpath2* | Any nodes matching *jsonpath1* with a child matching *jsonpath2* |
+--------------------------------------+-----------------------------------------------------------------------------------+
| *jsonpath1* ``wherenot`` *jsonpath2* | Any nodes matching *jsonpath1* with a child not matching *jsonpath2* |
+--------------------------------------+-----------------------------------------------------------------------------------+
| *jsonpath1* ``|`` *jsonpath2* | Any nodes matching the union of *jsonpath1* and *jsonpath2* |
+--------------------------------------+-----------------------------------------------------------------------------------+
Field specifiers ( *field* ):
+-------------------------+-------------------------------------------------------------------------------------+
| Syntax | Meaning |
+=========================+=====================================================================================+
| ``fieldname`` | the field ``fieldname`` (from the "current" object) |
+-------------------------+-------------------------------------------------------------------------------------+
| ``"fieldname"`` | same as above, for allowing special characters in the fieldname |
+-------------------------+-------------------------------------------------------------------------------------+
| ``'fieldname'`` | ditto |
+-------------------------+-------------------------------------------------------------------------------------+
| ``*`` | any field |
+-------------------------+-------------------------------------------------------------------------------------+
| *field* ``,`` *field* | either of the named fields (you can always build equivalent jsonpath using ``|``) |
+-------------------------+-------------------------------------------------------------------------------------+
Array specifiers ( *idx* ):
+-----------------------------------------+---------------------------------------------------------------------------------------+
| Syntax | Meaning |
+=========================================+=======================================================================================+
| ``[``\ *n*\ ``]`` | array index (may be comma-separated list) |
+-----------------------------------------+---------------------------------------------------------------------------------------+
| ``[``\ *start*\ ``?:``\ *end*\ ``?]`` | array slicing (note that *step* is unimplemented only due to lack of need thus far) |
+-----------------------------------------+---------------------------------------------------------------------------------------+
| ``[*]`` | any array index |
+-----------------------------------------+---------------------------------------------------------------------------------------+
Programmatic JSONPath
---------------------
If you are programming in Python and would like a more robust way to
create JSONPath expressions that does not depend on a parser, it is very
easy to do so directly, and here are some examples:
- ``Root()``
- ``Slice(start=0, end=None, step=None)``
- ``Fields('foo', 'bar')``
- ``Index(42)``
- ``Child(Fields('foo'), Index(42))``
- ``Where(Slice(), Fields('subfield'))``
- ``Descendants(jsonpath, jsonpath)``
Extras
------
- *Path data*: The result of ``JsonPath.find`` provide detailed context
and path data so it is easy to traverse to parent objects, print full
paths to pieces of data, and generate automatic ids.
- *Automatic Ids*: If you set ``jsonpath_ng.auto_id_field`` to a value
other than None, then for any piece of data missing that field, it
will be replaced by the JSONPath to it, giving automatic unique ids
to any piece of data. These ids will take into account any ids
already present as well.
- *Named operators*: Instead of using ``@`` to reference the current
object, this library uses ```this```. In general, any string
contained in backquotes can be made to be a new operator, currently
by extending the library.
Extensions
----------
To use the extensions below you must import from `jsonpath_ng.ext`.
+--------------+-----------------------------------------------+
| name | Example |
+==============+===============================================+
| len | - ``$.objects.`len``` |
+--------------+-----------------------------------------------+
| sub | - ``$.field.`sub(/foo\\\\+(.*)/, \\\\1)``` |
| | - ``$.field.`sub(/regex/, replacement)``` |
+--------------+-----------------------------------------------+
| split | - ``$.field.`split(+, 2, -1)``` |
| | - ``$.field.`split(",", *, -1)``` |
| | - ``$.field.`split(' ', -1, -1)``` |
| | - ``$.field.`split(sep, segement, maxsplit)```|
+--------------+-----------------------------------------------+
| sorted | - ``$.objects.`sorted``` |
| | - ``$.objects[\\some_field]`` |
| | - ``$.objects[\\some_field,/other_field]`` |
+--------------+-----------------------------------------------+
| filter | - ``$.objects[?(@some_field > 5)]`` |
| | - ``$.objects[?some_field = "foobar"]`` |
| | - ``$.objects[?some_field =~ "foobar"]`` |
| | - ``$.objects[?some_field > 5 & other < 2]`` |
| | |
| | Supported operators: |
| | - Equality: ==, =, != |
| | - Comparison: >, >=, <, <= |
| | - Regex match: =~ |
| | |
| | Combine multiple criteria with '&'. |
| | |
| | Properties can only be compared to static |
| | values. |
+--------------+-----------------------------------------------+
| arithmetic | - ``$.foo + "_" + $.bar`` |
| (-+*/) | - ``$.foo * 12`` |
| | - ``$.objects[*].cow + $.objects[*].cat`` |
+--------------+-----------------------------------------------+
About arithmetic and string
---------------------------
Operations are done with python operators and allows types that python
allows, and return [] if the operation can be done due to incompatible types.
When operators are used, a jsonpath must be be fully defined otherwise
jsonpath-rw-ext can't known if the expression is a string or a jsonpath field,
in this case it will choice string as type.
Example with data::
{
'cow': 'foo',
'fish': 'bar'
}
| ``cow + fish`` returns ``cowfish``
| ``$.cow + $.fish`` returns ``foobar``
| ``$.cow + "_" + $.fish`` returns ``foo_bar``
| ``$.cow + "_" + fish`` returns ``foo_fish``
About arithmetic and list
-------------------------
Arithmetic can be used against two lists if they have the same size.
Example with data::
{'objects': [
{'cow': 2, 'cat': 3},
{'cow': 4, 'cat': 6}
]}
| ``$.objects[\*].cow + $.objects[\*].cat`` returns ``[6, 9]``
More to explore
---------------
There are way too many JSONPath implementations out there to discuss.
Some are robust, some are toy projects that still work fine, some are
exercises. There will undoubtedly be many more. This one is made for use
in released, maintained code, and in particular for programmatic access
to the abstract syntax and extension. But JSONPath at its simplest just
isn't that complicated, so you can probably use any of them
successfully. Why not this one?
The original proposal, as far as I know:
- `JSONPath - XPath for
JSON <http://goessner.net/articles/JSONPath/>`__ by Stefan Goessner.
Other examples
--------------
Loading json data from file
.. code:: python
import json
d = json.loads('{"foo": [{"baz": 1}, {"baz": 2}]}')
# or
with open('myfile.json') as f:
d = json.load(f)
Special note about PLY and docstrings
-------------------------------------
The main parsing toolkit underlying this library,
`PLY <https://github.com/dabeaz/ply>`__, does not work with docstrings
removed. For example, ``PYTHONOPTIMIZE=2`` and ``python -OO`` will both
cause a failure.
Contributors
------------
This package is authored and maintained by:
- `Kenn Knowles <https://github.com/kennknowles>`__
(`@kennknowles <https://twitter.com/KennKnowles>`__)
- `Tomas Aparicio <https://github.com/h2non>`
with the help of patches submitted by `these contributors <https://github.com/kennknowles/python-jsonpath-ng/graphs/contributors>`__.
Copyright and License
---------------------
Copyright 2013 - Kenneth Knowles
Copyright 2017 - Tomas Aparicio
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
::
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
.. _`JSONPath proposal`: http://goessner.net/articles/JsonPath/
.. _`jsonpath-rw`: https://github.com/kennknowles/python-jsonpath-rw
.. _`jsonpath-rw-ext`: https://pypi.python.org/pypi/jsonpath-rw-ext/
.. |PyPi downloads| image:: https://pypip.in/d/jsonpath-ng/badge.png
:target: https://pypi.python.org/pypi/jsonpath-ng
.. |Build Status| image:: https://github.com/h2non/jsonpath-ng/actions/workflows/ci.yml/badge.svg
:target: https://github.com/h2non/jsonpath-ng/actions/workflows/ci.yml
.. |PyPI| image:: https://img.shields.io/pypi/v/jsonpath-ng.svg?maxAge=2592000?style=flat-square
:target: https://pypi.python.org/pypi/jsonpath-ng
Raw data
{
"_id": null,
"home_page": "https://github.com/h2non/jsonpath-ng",
"name": "jsonpath-ng",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": null,
"author": "Tomas Aparicio",
"author_email": "tomas@aparicio.me",
"download_url": "https://files.pythonhosted.org/packages/6d/86/08646239a313f895186ff0a4573452038eed8c86f54380b3ebac34d32fb2/jsonpath-ng-1.7.0.tar.gz",
"platform": null,
"description": "Python JSONPath Next-Generation |Build Status| |PyPI|\n=====================================================\n\nA final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic\nand binary comparison operators, as defined in the original `JSONPath proposal`_.\n\nThis packages merges both `jsonpath-rw`_ and `jsonpath-rw-ext`_ and\nprovides several AST API enhancements, such as the ability to update or remove nodes in the tree.\n\nAbout\n-----\n\nThis library provides a robust and significantly extended implementation\nof JSONPath for Python. It is tested with CPython 3.8 and higher.\n\nThis library differs from other JSONPath implementations in that it is a\nfull *language* implementation, meaning the JSONPath expressions are\nfirst class objects, easy to analyze, transform, parse, print, and\nextend.\n\nQuick Start\n-----------\n\nTo install, use pip:\n\n.. code:: bash\n\n $ pip install --upgrade jsonpath-ng\n\n\nUsage\n-----\n\nBasic examples:\n\n.. code:: python\n\n $ python\n\n >>> from jsonpath_ng import jsonpath, parse\n\n # A robust parser, not just a regex. (Makes powerful extensions possible; see below)\n >>> jsonpath_expr = parse('foo[*].baz')\n\n # Extracting values is easy\n >>> [match.value for match in jsonpath_expr.find({'foo': [{'baz': 1}, {'baz': 2}]})]\n [1, 2]\n\n # Matches remember where they came from\n >>> [str(match.full_path) for match in jsonpath_expr.find({'foo': [{'baz': 1}, {'baz': 2}]})]\n ['foo.[0].baz', 'foo.[1].baz']\n\n # Modifying values matching the path\n >>> jsonpath_expr.update( {'foo': [{'baz': 1}, {'baz': 2}]}, 3)\n {'foo': [{'baz': 3}, {'baz': 3}]}\n\n # Modifying one of the values matching the path\n >>> matches = jsonpath_expr.find({'foo': [{'baz': 1}, {'baz': 2}]})\n >>> matches[0].full_path.update( {'foo': [{'baz': 1}, {'baz': 2}]}, 3)\n {'foo': [{'baz': 3}, {'baz': 2}]}\n\n # Removing all values matching a path\n >>> jsonpath_expr.filter(lambda d: True, {'foo': [{'baz': 1}, {'baz': 2}]})\n {'foo': [{}, {}]}\n\n # Removing values containing particular data matching path\n >>> jsonpath_expr.filter(lambda d: d == 2, {'foo': [{'baz': 1}, {'baz': 2}]})\n {'foo': [{'baz': 1}, {}]}\n\n # And this can be useful for automatically providing ids for bits of data that do not have them (currently a global switch)\n >>> jsonpath.auto_id_field = 'id'\n >>> [match.value for match in parse('foo[*].id').find({'foo': [{'id': 'bizzle'}, {'baz': 3}]})]\n ['foo.bizzle', 'foo.[1]']\n\n # A handy extension: named operators like `parent`\n >>> [match.value for match in parse('a.*.b.`parent`.c').find({'a': {'x': {'b': 1, 'c': 'number one'}, 'y': {'b': 2, 'c': 'number two'}}})]\n ['number two', 'number one']\n\n # You can also build expressions directly quite easily\n >>> from jsonpath_ng.jsonpath import Fields\n >>> from jsonpath_ng.jsonpath import Slice\n\n >>> jsonpath_expr_direct = Fields('foo').child(Slice('*')).child(Fields('baz')) # This is equivalent\n\n\nUsing the extended parser:\n\n.. code:: python\n\n $ python\n\n >>> from jsonpath_ng.ext import parse\n\n # A robust parser, not just a regex. (Makes powerful extensions possible; see below)\n >>> jsonpath_expr = parse('foo[*].baz')\n\n\nJSONPath Syntax\n---------------\n\nThe JSONPath syntax supported by this library includes some additional\nfeatures and omits some problematic features (those that make it\nunportable). In particular, some new operators such as ``|`` and\n``where`` are available, and parentheses are used for grouping not for\ncallbacks into Python, since with these changes the language is not\ntrivially associative. Also, fields may be quoted whether or not they\nare contained in brackets.\n\nAtomic expressions:\n\n+-----------------------+---------------------------------------------------------------------------------------------+\n| Syntax | Meaning |\n+=======================+=============================================================================================+\n| ``$`` | The root object |\n+-----------------------+---------------------------------------------------------------------------------------------+\n| ```this``` | The \"current\" object. |\n+-----------------------+---------------------------------------------------------------------------------------------+\n| ```foo``` | More generally, this syntax allows \"named operators\" to extend JSONPath is arbitrary ways |\n+-----------------------+---------------------------------------------------------------------------------------------+\n| *field* | Specified field(s), described below |\n+-----------------------+---------------------------------------------------------------------------------------------+\n| ``[`` *field* ``]`` | Same as *field* |\n+-----------------------+---------------------------------------------------------------------------------------------+\n| ``[`` *idx* ``]`` | Array access, described below (this is always unambiguous with field access) |\n+-----------------------+---------------------------------------------------------------------------------------------+\n\nJsonpath operators:\n\n+--------------------------------------+-----------------------------------------------------------------------------------+\n| Syntax | Meaning |\n+======================================+===================================================================================+\n| *jsonpath1* ``.`` *jsonpath2* | All nodes matched by *jsonpath2* starting at any node matching *jsonpath1* |\n+--------------------------------------+-----------------------------------------------------------------------------------+\n| *jsonpath* ``[`` *whatever* ``]`` | Same as *jsonpath*\\ ``.``\\ *whatever* |\n+--------------------------------------+-----------------------------------------------------------------------------------+\n| *jsonpath1* ``..`` *jsonpath2* | All nodes matched by *jsonpath2* that descend from any node matching *jsonpath1* |\n+--------------------------------------+-----------------------------------------------------------------------------------+\n| *jsonpath1* ``where`` *jsonpath2* | Any nodes matching *jsonpath1* with a child matching *jsonpath2* |\n+--------------------------------------+-----------------------------------------------------------------------------------+\n| *jsonpath1* ``wherenot`` *jsonpath2* | Any nodes matching *jsonpath1* with a child not matching *jsonpath2* |\n+--------------------------------------+-----------------------------------------------------------------------------------+\n| *jsonpath1* ``|`` *jsonpath2* | Any nodes matching the union of *jsonpath1* and *jsonpath2* |\n+--------------------------------------+-----------------------------------------------------------------------------------+\n\nField specifiers ( *field* ):\n\n+-------------------------+-------------------------------------------------------------------------------------+\n| Syntax | Meaning |\n+=========================+=====================================================================================+\n| ``fieldname`` | the field ``fieldname`` (from the \"current\" object) |\n+-------------------------+-------------------------------------------------------------------------------------+\n| ``\"fieldname\"`` | same as above, for allowing special characters in the fieldname |\n+-------------------------+-------------------------------------------------------------------------------------+\n| ``'fieldname'`` | ditto |\n+-------------------------+-------------------------------------------------------------------------------------+\n| ``*`` | any field |\n+-------------------------+-------------------------------------------------------------------------------------+\n| *field* ``,`` *field* | either of the named fields (you can always build equivalent jsonpath using ``|``) |\n+-------------------------+-------------------------------------------------------------------------------------+\n\nArray specifiers ( *idx* ):\n\n+-----------------------------------------+---------------------------------------------------------------------------------------+\n| Syntax | Meaning |\n+=========================================+=======================================================================================+\n| ``[``\\ *n*\\ ``]`` | array index (may be comma-separated list) |\n+-----------------------------------------+---------------------------------------------------------------------------------------+\n| ``[``\\ *start*\\ ``?:``\\ *end*\\ ``?]`` | array slicing (note that *step* is unimplemented only due to lack of need thus far) |\n+-----------------------------------------+---------------------------------------------------------------------------------------+\n| ``[*]`` | any array index |\n+-----------------------------------------+---------------------------------------------------------------------------------------+\n\nProgrammatic JSONPath\n---------------------\n\nIf you are programming in Python and would like a more robust way to\ncreate JSONPath expressions that does not depend on a parser, it is very\neasy to do so directly, and here are some examples:\n\n- ``Root()``\n- ``Slice(start=0, end=None, step=None)``\n- ``Fields('foo', 'bar')``\n- ``Index(42)``\n- ``Child(Fields('foo'), Index(42))``\n- ``Where(Slice(), Fields('subfield'))``\n- ``Descendants(jsonpath, jsonpath)``\n\n\nExtras\n------\n\n- *Path data*: The result of ``JsonPath.find`` provide detailed context\n and path data so it is easy to traverse to parent objects, print full\n paths to pieces of data, and generate automatic ids.\n- *Automatic Ids*: If you set ``jsonpath_ng.auto_id_field`` to a value\n other than None, then for any piece of data missing that field, it\n will be replaced by the JSONPath to it, giving automatic unique ids\n to any piece of data. These ids will take into account any ids\n already present as well.\n- *Named operators*: Instead of using ``@`` to reference the current\n object, this library uses ```this```. In general, any string\n contained in backquotes can be made to be a new operator, currently\n by extending the library.\n\n\nExtensions\n----------\n\nTo use the extensions below you must import from `jsonpath_ng.ext`.\n\n+--------------+-----------------------------------------------+\n| name | Example |\n+==============+===============================================+\n| len | - ``$.objects.`len``` |\n+--------------+-----------------------------------------------+\n| sub | - ``$.field.`sub(/foo\\\\\\\\+(.*)/, \\\\\\\\1)``` |\n| | - ``$.field.`sub(/regex/, replacement)``` |\n+--------------+-----------------------------------------------+\n| split | - ``$.field.`split(+, 2, -1)``` |\n| | - ``$.field.`split(\",\", *, -1)``` |\n| | - ``$.field.`split(' ', -1, -1)``` |\n| | - ``$.field.`split(sep, segement, maxsplit)```|\n+--------------+-----------------------------------------------+\n| sorted | - ``$.objects.`sorted``` |\n| | - ``$.objects[\\\\some_field]`` |\n| | - ``$.objects[\\\\some_field,/other_field]`` |\n+--------------+-----------------------------------------------+\n| filter | - ``$.objects[?(@some_field > 5)]`` |\n| | - ``$.objects[?some_field = \"foobar\"]`` |\n| | - ``$.objects[?some_field =~ \"foobar\"]`` |\n| | - ``$.objects[?some_field > 5 & other < 2]`` |\n| | |\n| | Supported operators: |\n| | - Equality: ==, =, != |\n| | - Comparison: >, >=, <, <= |\n| | - Regex match: =~ |\n| | |\n| | Combine multiple criteria with '&'. |\n| | |\n| | Properties can only be compared to static |\n| | values. |\n+--------------+-----------------------------------------------+\n| arithmetic | - ``$.foo + \"_\" + $.bar`` |\n| (-+*/) | - ``$.foo * 12`` |\n| | - ``$.objects[*].cow + $.objects[*].cat`` |\n+--------------+-----------------------------------------------+\n\nAbout arithmetic and string\n---------------------------\n\nOperations are done with python operators and allows types that python\nallows, and return [] if the operation can be done due to incompatible types.\n\nWhen operators are used, a jsonpath must be be fully defined otherwise\njsonpath-rw-ext can't known if the expression is a string or a jsonpath field,\nin this case it will choice string as type.\n\nExample with data::\n\n {\n 'cow': 'foo',\n 'fish': 'bar'\n }\n\n| ``cow + fish`` returns ``cowfish``\n| ``$.cow + $.fish`` returns ``foobar``\n| ``$.cow + \"_\" + $.fish`` returns ``foo_bar``\n| ``$.cow + \"_\" + fish`` returns ``foo_fish``\n\nAbout arithmetic and list\n-------------------------\n\nArithmetic can be used against two lists if they have the same size.\n\nExample with data::\n\n {'objects': [\n {'cow': 2, 'cat': 3},\n {'cow': 4, 'cat': 6}\n ]}\n\n| ``$.objects[\\*].cow + $.objects[\\*].cat`` returns ``[6, 9]``\n\nMore to explore\n---------------\n\nThere are way too many JSONPath implementations out there to discuss.\nSome are robust, some are toy projects that still work fine, some are\nexercises. There will undoubtedly be many more. This one is made for use\nin released, maintained code, and in particular for programmatic access\nto the abstract syntax and extension. But JSONPath at its simplest just\nisn't that complicated, so you can probably use any of them\nsuccessfully. Why not this one?\n\nThe original proposal, as far as I know:\n\n- `JSONPath - XPath for\n JSON <http://goessner.net/articles/JSONPath/>`__ by Stefan Goessner.\n\nOther examples\n--------------\n\nLoading json data from file\n\n.. code:: python\n\n import json\n d = json.loads('{\"foo\": [{\"baz\": 1}, {\"baz\": 2}]}')\n # or\n with open('myfile.json') as f:\n d = json.load(f)\n\nSpecial note about PLY and docstrings\n-------------------------------------\n\nThe main parsing toolkit underlying this library,\n`PLY <https://github.com/dabeaz/ply>`__, does not work with docstrings\nremoved. For example, ``PYTHONOPTIMIZE=2`` and ``python -OO`` will both\ncause a failure.\n\nContributors\n------------\n\nThis package is authored and maintained by:\n\n- `Kenn Knowles <https://github.com/kennknowles>`__\n (`@kennknowles <https://twitter.com/KennKnowles>`__)\n- `Tomas Aparicio <https://github.com/h2non>`\n\nwith the help of patches submitted by `these contributors <https://github.com/kennknowles/python-jsonpath-ng/graphs/contributors>`__.\n\nCopyright and License\n---------------------\n\nCopyright 2013 - Kenneth Knowles\n\nCopyright 2017 - Tomas Aparicio\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may\nnot use this file except in compliance with the License. You may obtain\na copy of the License at\n\n::\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n.. _`JSONPath proposal`: http://goessner.net/articles/JsonPath/\n.. _`jsonpath-rw`: https://github.com/kennknowles/python-jsonpath-rw\n.. _`jsonpath-rw-ext`: https://pypi.python.org/pypi/jsonpath-rw-ext/\n\n.. |PyPi downloads| image:: https://pypip.in/d/jsonpath-ng/badge.png\n :target: https://pypi.python.org/pypi/jsonpath-ng\n.. |Build Status| image:: https://github.com/h2non/jsonpath-ng/actions/workflows/ci.yml/badge.svg\n :target: https://github.com/h2non/jsonpath-ng/actions/workflows/ci.yml\n.. |PyPI| image:: https://img.shields.io/pypi/v/jsonpath-ng.svg?maxAge=2592000?style=flat-square\n :target: https://pypi.python.org/pypi/jsonpath-ng",
"bugtrack_url": null,
"license": "Apache 2.0",
"summary": "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming.",
"version": "1.7.0",
"project_urls": {
"Homepage": "https://github.com/h2non/jsonpath-ng"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6d8608646239a313f895186ff0a4573452038eed8c86f54380b3ebac34d32fb2",
"md5": "5665ac3d5b022ac17fb83628cb4f2069",
"sha256": "f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c"
},
"downloads": -1,
"filename": "jsonpath-ng-1.7.0.tar.gz",
"has_sig": false,
"md5_digest": "5665ac3d5b022ac17fb83628cb4f2069",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 37838,
"upload_time": "2024-10-11T15:41:42",
"upload_time_iso_8601": "2024-10-11T15:41:42.404992Z",
"url": "https://files.pythonhosted.org/packages/6d/86/08646239a313f895186ff0a4573452038eed8c86f54380b3ebac34d32fb2/jsonpath-ng-1.7.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-11 15:41:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "h2non",
"github_project": "jsonpath-ng",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"requirements": [
{
"name": "ply",
"specs": []
},
{
"name": "setuptools",
"specs": [
[
">=",
"18.5"
]
]
}
],
"tox": true,
"lcname": "jsonpath-ng"
}