adriank / objectpath Goto Github PK
View Code? Open in Web Editor NEWThe agile query language for semi-structured data
Home Page: http://objectpath.org
License: MIT License
The agile query language for semi-structured data
Home Page: http://objectpath.org
License: MIT License
Use ObjectPathPy/test.json for test:
L:\OtherProjects\json_path_query\ObjectPathPy>python ObjectPath.py -o test.json
ObjectPath interactive shell
ctrl+c to exit.
{}
JSON file loaded from test.json
>>> $.store.book.*[price is 8.95]
[{u'category': u'reference', u'price': 8.95, u'title': u'Sayings of the Century', u'author': u'Nigel Rees'}]
>>> $..store.book.*[price is 8.95]
[]
>>> $..book.*[price is 8.95]
[]
>>> $..store.book[price is 8.95]
[]
>>> $..book[price is 8.95]
[]
>>>
The first try uses full path "$.store.book.*[price is 8.95]"
or "$.store.book[price is 8.95]"
and we can get the book of which price is 8.95.
But "$..store.book.*[price is 8.95]"
or "$..book[price is 8.95]"
(used in situations that the required item is too deep to describe all parent nodes) does not work.
Could you fix that?
Anyway, it's an awesome lib:) Thanks.
How to write jsonpath when multiple array selectors are required?
In the bellow python
example the I want to select {"d": 10, "e": 20}
first jsonpath looks correct but does not work. The other ones have side effects.
from objectpath import Tree
a={
"a": [
{
"b":1,
"c": [
{"d": 10, "e": 20},
{"d": 30, "e": {"d": 10, "e": 11}},
],
"b2": {
"c":[
{"d":10, "e": 12}
]
}
},
{"b": 2}
]
}
print list(Tree(a).execute("$.a[@.b is 1].c[@.d is 10]"))
print list(Tree(a).execute("$.a[@.b is 1].c..*[@.d is 10]"))
print list(Tree(a).execute("$.a[@.b is 1]..c[@.d is 10]"))
Output:
[]
[{'e': 20, 'd': 10}, {'e': 11, 'd': 10}]
[{'e': 20, 'd': 10}, {'e': 12, 'd': 10}]
replace import objectpath
with from objectpath import Tree
Interesting project. Any chance to make the python library portably available via pip install
?
I wish to use a python notebook, ie jupyter with this library. I could only get the most trivial example to work. Any ideas?
thank you!
Anne
This works, returning '1'
http://objectpath.org/tutorial.html
from objectpath import *
tree1=Tree({"a":1})
tree1.execute("$.a")
None of the complex json example is working;
json3 = '{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 } ] }}'
tree3=Tree(json3)
tree3.execute("$") # ("$.store.book[0].price")
/Users/ME/anaconda/envs/py27/lib/python2.7/site-packages/objectpath/core/interpreter.pyc in execute(self, expr)
603 D=self.D
604 if type(expr) in STR_TYPES:
--> 605 tree=self.compile(expr)
606 elif type(expr) not in (tuple,list,dict):
607 return expr
/Users/ME/anaconda/envs/py27/lib/python2.7/site-packages/objectpath/core/interpreter.pyc in compile(self, expr)
36 if expr in EXPR_CACHE:
37 return EXPR_CACHE[expr]
---> 38 ret=EXPR_CACHE[expr]=parse(expr,self.D)
39 return ret
40
/Users/ME/anaconda/envs/py27/lib/python2.7/site-packages/objectpath/core/parser.pyc in parse(expr, D)
462 nextToken=tokenize(expr).next
463 token=nextToken()
--> 464 r=expression().getTree()
465 if D:
466 print ("PARSE STAGE")
/Users/ME/anaconda/envs/py27/lib/python2.7/site-packages/objectpath/core/parser.pyc in expression(rbp)
443 t=token
444 token=nextToken()
--> 445 left=t.nud()
446 while rbp < token.lbp:
447 t=token
/Users/ME/anaconda/envs/py27/lib/python2.7/site-packages/objectpath/core/parser.pyc in nud(self)
276 else:
277 self.fst=token.value
--> 278 advance()
279 return self
280
/Users/ME/anaconda/envs/py27/lib/python2.7/site-packages/objectpath/core/parser.pyc in advance(ID)
159 if ID and token.id != ID:
160 raise SyntaxError("Expected %r, got %s"%(ID,token.id))
--> 161 token=nextToken()
162
163 def method(s):
StopIteration:
I am using;
$ source activate py27;
discarding /Users/ME/anaconda/bin from PATH
prepending /Users/ME/anaconda/envs/py27/bin to PATH
$ python --version ; pip --version
Python 2.7.11 :: Continuum Analytics, Inc.
pip 8.1.2 from /Users/ME/anaconda/envs/py27/lib/python2.7/site-packages (python 2.7)
$ ipython --version ; jupyter --version
4.2.0
4.1.0
I am using the books (json) that you are using in the tutorial and I would like to retrieve the result of the following query:
$..[@.author is 'Evelyn Waugh' and @.title is 'Sword of Honour'] and $..[@.author is 'Nigel Rees' and @.title is 'Sayings of the Century']
this returns only 1 object:
[{
"category": "reference",
"price": 8.95,
"title": "Sayings of the Century",
"author": "Nigel Rees"
}]
I would expect to get two entities back, one for Sword of Honour and one for Sayings of the Century. Is this feasible?
Invalid queries return valid results on non-object elements of the tree (e.g. numbers, strings, sequence of strings)
Using the dataset from main page:
$ objectpath -u "http://api.openweathermap.org/data/2.5/box/city?bbox=12,32,15,37,10&cluster=yes"
>>> $.cnt
15
>>> $.cnt.11
15
>>> $.cnt.wtf?
15
>>> $.cod.foo
"200"
>>> $.cod.foo.asd
"200"
>>> $.cod.foo.asd[asd]
"200"
>>> $.cod.foo.bar['???']
"200"
Same applies to sequences of strings:
$ cat > test.json
{"list": [1,2,3,4]}
$ objectpath test.json
>>> $.list
[
1,
2,
3,
4
]
>>> $.list.123
[
1,
2,
3,
4
]
>>> $.list.abc
[]
in Python last line yields an empty generator.
Hey there, I was wondering if it was possible to do recursion of expressions?
Like so:
{
attachments: $.items[ { title: @.name } ]
}
Which would result in:
[
{ title: somename },
{ title: somename2 }
]
I have a use use case where I must filter data on some values which contain a leading slash (ie. "/tmp"). This data is loaded from a JSON file so it ends up in unicode and I cannot find a way to filter this. Here is an example:
data = {
"store": {
"book": [
{
"category": "/fiction",
"title": "str /fiction"
},
{
"category": u"/fiction",
"title": "unicode /fiction"
},
{
"category": "fiction/",
"title": "str fiction/"
},
{
"category": u"fiction/",
"title": "unicode fiction/"
},
]
}
}
tree = Tree(data)
tree.execute("$.store.book[@.category is '/fiction']") # ==> 1 match ("str /fiction")
tree.execute("$.store.book[@.category is 'fiction/']") # ==> 2 matches
Thanks
If I want to get back the whole document, I get an error.
Here the code:
ee = objectpath.Tree({'aa':'bb', 'cc': {'ee':'11', 'rr': '33'}})
ee.execute("$.cc") --> works
ee.execute("$") --> throws exception "StopIteration"
Any plans to support?
I would like to
>>> import datetime
>>> import objectpath
>>> objectpath.Tree(datetime).execute("$.*.now")
Currently we have +
for union operation to combine two or more collections together. This is very helpful in the way you can split your desired results into sub-sections and write different query paths for each. In addition to +
, in certain use cases, more collection operators will prove their usefulness (borrowing from set theory).
I am proposing 2 new collection operators: intersection and difference. These operations require operands to have non duplicate elements. So for these operations, there will be two modes: by-ref and by-value. A
and B
are by-ref equal if they have the excact same path. A
and B
are by-value equal if they have the same primitive value or all fields of them are by-value equal.
An array can be a set as long as there are no two elements equal to each other. If otherwise, duplicates are removed before performing any of the set operations.
^
(by-ref) and .^
(by-value)A ^ B
is an intersection of A
and A
iff every element in A ^ B
is contained by both A
and B
.
poems:
- name: The Bronze Horseman
author: Pushkin
- name: Devils
author: Pushkin
- name: Oh, Laziness, Come...
author: Pushkin
- name: Gitanjali
author: Tagore
- name: Manasi
author: Tagore
- name: Sonar Tori
author: Tagore
novels:
- name: Gitanjali
author: Tagore
- name: Noukadubi
author: Tagore
- name: Les Misérables
author: Victor Hugo
$.poems.author .^ $.novels.author
$.poems.author
=> Pushkin, Pushkin, Pushkin, Tagore, Tagore, Tagore
$.novels.author
=> Tagore, Tagore, Victor Hugo
$.poems.author
=> Pushkin, Tagore
$.poems.author .^ $.novels.author
=> Tagore
$.poems.author ^ $.novels.author
$.poems.author
=> <poems[0].author>, ..., <poems[5].author>
$.novels.author
=> <novels[0].author>, ..., <novels[2].author>
$.poems.author ^ $.novels.author
=> <None>
$..*[@.author is 'Tagore'] ^ $.novels
($..*[@.author is 'Tagore']
=> <poems[3]>, <poem[4]>, <poem[5]>, <novels[0]>, <novels[1]>
$.novels
=> <novels[0]>, ..., <novels[5]>
$..*[@.author is 'Tagore'] ^ $.novels
=> <novels[0]>, <novels[1]>
$.poems .^ $.novels
=> {name: Gitanjali, author: Tagore}
-
and .-
A - B
is a complement of B
in A
(or difference of A
and B
) iff every element in A - B
is contained by A
but not by B
.
$.poems.author - $.novels.author
=> Pushkin, Pushkin, Pushkin, Tagore, Tagore, Tagore
$.poems.author .- $.novels.author
=> Pushkin
($..*[@.author is 'Tagore'] - $.novels).name
=> Gitanjali, Manasi, Sonar Tori
For performance concerns, A - B
should only evaluate B
within results of A
.
This caught me out since I couldn't work out what was wrong with my expression - turned out it was that I was passing in a unicode expression and not a str.
Hi,
I have this sample json file as shown below
{"coord":{"lon":139,"lat":35},
"sys":{"country":"JP","sunrise":1369769524,"sunset":1369821049},
"weather":[{"id":804,"main":"clouds","description":"overcast clouds","icon":"04n"}],
"main":{"temp":289.5,"humidity":89,"pressure":1013,"temp_min":287.04,"temp_max":292.04},
"wind":{"speed":7.31,"deg":187.002},
"rain":{"3h":0},
"clouds":{"all":92},
"dt":1369824698,
"id":1851632,
"name":"Shuzenji",
"cod":200}
The query $..*[@..temp > 10].name works
but the query $..*[@.icon is "04n"].name doesn't work.
any insights?
For a family like this (the actually data can go very deep):
name: Adam
gender: male
children:
- name: Bran
gender: male
- name: Cindy
gender: female
children:
- name: David
gender: male
children:
- name: Helen
gender: female
- name: Eva
gender: female
- name: Frank
gender: male
children:
- name: George
gender: male
I'd like to find Cindy and all female offsprings of Cindy. There will be three steps to take:
$..*[@.name is 'Cindy'].name
=> Cindy
$..*[@.name is 'Cindy'].children..*[@.gender is female].name
=> Helen, Eva
$..*[@.name is 'Cindy'].name + $..*[@.name is 'Cindy'].children..*[@.gender is female].name
=> Cindy, Helen, Eva
And now you can see the pattern is already unbearable long due to repetition of finding Cindy
pattern. In more complex cases, repetition will make the pattern practically unmaintainable. Currently in my application, I am using a following pattern (with a self-written preprocessor):
$cindy := $..*[@.name is 'Cindy']
$cindy.name + $cindy.children..*[@.gender is female].name
This expands to $..*[@.name is 'Cindy'].name + $..*[@.name is 'Cindy'].children..*[@.gender is female].name
.
Another thing I am looking for is the ability to delete certain objects from collection. Suppose I need to find Cindy and all female offsprings of Cindy except David's children. I don't know if it is even possible at the current stage. Since we have '+' for union, I propose use '-' for subtraction.
(The assign operators are aligned only for aesthetics reasons)
$cindy := $..*[@.name is 'Cindy']
$cindy_bloodline := $cindy.name + $cindy.children..*[@.gender is female].name
$david_bloodline := $..*[@.name is 'David'].children..*.name
$cindy_bloodline - $david_bloodline
The library failing with the following error:
AttributeError: 'tuple' object has no attribute 'major'
As per our discussion in #46, I would like to add to the list of features the possibility to select keys that respect a certain pattern - equivalent to XPath matches
(https://www.w3.org/TR/xpath-functions/#func-matches).
I have a dictionary like:- {"node1": " value1", "node (%)": "value 2", "node 3": "value2"}
and I am trying to access $.node 3
or $.node (%)
then it is throwing SyntaxError
.
Support on this will be very helpful.
A query looking for a specific float number will match the exact float and for some reason also the integer. E.g. looking for the number 9.891 will find 9.891 but also 9, however 9.8 will not be found.
Somehow the query does work if the value is converted into a float.
from objectpath import Tree
input = {
"item_1": {
"value": "foo",
"x": 5.6,
"y": 9
},
"item_2": {
"value": "bar",
"x": 5.6,
"y": 9.891
},
"item_3": {
"value": "foobar",
"x": 5.6,
"y": 9.8
}
}
op = Tree(input)
query = "$..*[@.x is 5.6 and @.y is 9.891].value"
result = list(op.execute(query))
>>> ['foo', 'bar']
query = "$..*[float(@.x) is 5.6 and float(@.y) is 9.891].value"
result = list(op.execute(query))
>>> ['bar']
I have a json data structure that looks like this:
{ "version": "14",
"data": {
"applications": [
{
"id": 1,
"enabled": true,
"policy": [
]
},
{
"id": 2,
"enabled": true,
"policy": [
{
"type": "Rule",
"id": 5
}
]
}
]
}
I am trying to return the ID of the application when policy id = 5 (or some other int value).
I thought that: $.data.applications[@.policy.*.id is 5].id would work, but i get an empty set []
I also tried: $.data.applications[@.policy..id is 5].id
using "jq" i can do the following:
#cat jsonData.json | jq ‘.data.applications[] | select(.policy[].id == 5) | .id’
13
14
15
16
17
18
19
21
22
23
24
39
Is this query functionality not possible using objectPath?
Microsecond handling seems to not be working properly
$ python -c 'import objectpath; print(objectpath.Tree({}).execute("""time([0,0,0,1])"""))'
00:00:00.000001
$ python -c 'import objectpath; print(objectpath.Tree({}).execute("""time([0,0]) - time([0,0,0,1])"""))'
23:59:59.009999
but
>>> datetime.datetime(1970,1,1,0,0) - datetime.datetime(1970,1,1,0,0,0,1)
datetime.timedelta(-1, 86399, 999999)
Notice the number of 9:s
Another sign of the strange microsecond handling is that subtraction of certain values fail:
$ python -c 'import objectpath; print(objectpath.Tree({}).execute("""time([0,0,0,999999])"""))'
00:00:00.999999
$ python -c 'import objectpath; print(objectpath.Tree({}).execute("""time([0,0]) - time([0,0,0,999999])"""))'
Traceback (most recent call last):
File "/home/ubuntu/env/lib/python3.6/site-packages/objectpath/core/interpreter.py", line 158, in exe
return fst-snd
TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/ubuntu/env/lib/python3.6/site-packages/objectpath/core/interpreter.py", line 646, in execute
ret=exe(tree)
File "/home/ubuntu/env/lib/python3.6/site-packages/objectpath/core/interpreter.py", line 164, in exe
return timeutils.subTimes(fst,snd)
File "/home/ubuntu/env/lib/python3.6/site-packages/objectpath/utils/timeutils.py", line 169, in subTimes
return datetime.time(*reversed(t2))
ValueError: microsecond must be in 0..999999
Thanks for ObjectPath, it is great! I started to play with it recently and found that number-leading atributes are not recognized by parser. This is a part of openweathermap json response:
>>> from objectpath import Tree
>>> tree=Tree({'3h':1})
>>> tree.execute("$.3h")
{'3h': 1}
I also found workaround, which gives me expected result:
>>>> tree.execute("$.*['3h'][0]")
1
But in some complex cases workaround does not work either.
I want to find the element of the array where firstName is John and has a phoneNumber of type iPhone.
[{
"firstName": "John",
"age" : 26,
"phoneNumbers": [
{
"type" : "iPhone",
"number": "0123-4567-8888"
},
{
"type" : "home",
"number": "0123-4567-8910"
}
]
},
{
"firstName": "Johny",
"lastName" : "doe",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
},
"phoneNumbers": [
{
"type" : "iPhone",
"number": "0123-4567-8888"
},
{
"type" : "home",
"number": "0123-4567-8910"
}
]
}]
However I received a syntax error. Here is the session:
Loading JSON document from simple.json... done.
$..[@.firstName is 'John']
[{
"age": 26,
"phoneNumbers": [
{
"type": "iPhone",
"number": "0123-4567-8888"
},
{
"type": "home",
"number": "0123-4567-8910"
}
],
"firstName": "John"
}]
$..[@.firstName is 'John' and @.phoneNumbers[].type is 'iPhone']
Syntax error ('').
What I am doing wrong?
Thanks in advance.
I'm not asking you to do it, just asking if there are plans.
Hi!
It's my first time using ObjectPath, and I'm getting this error:
Traceback (most recent call last):
File "script.py", line 19, in <module>
res = tree.execute('$.issues[@.changelog.histories[@.items[0].toString is "Done"]]')
File "C:\Users\cmmartins\AppData\Local\Programs\Python\Python37-32\lib\site-packages\objectpath\core\interpreter.py", line 608, in execute
ret=exe(tree)
File "C:\Users\cmmartins\AppData\Local\Programs\Python\Python37-32\lib\site-packages\objectpath\core\interpreter.py", line 328, in exe
nodeList_append(exe((selector[0],exe(selector[1]),exe(selector[2]))))
File "C:\Users\cmmartins\AppData\Local\Programs\Python\Python37-32\lib\site-packages\objectpath\core\interpreter.py", line 234, in exe
return ret
UnboundLocalError: local variable 'ret' referenced before assignment
I don't know if my query is wrong (toString is a property, maybe this is the problem?) but the error is not being treated. I saw this issue in another repo (miguelgrinberg/python-socketio#85), maybe this guy solution helps you.
Thank you!
keys(sum($.))
Argument is not object but int in keys()
keys($.)
Argument is not object but list in keys()
Also keys(sum($.*) doesn't work.
I have a JSON-LD style document that contains ":" as a namespace separator in the object's keys, so something like:
{
"dc:identifier" : [{"type" : "identifier type", "id" : "identifier"}]
}
When I do
t = Tree(doc)
t.execute("$.dc:identifier")
I get nothing back.
If I add a key which does not have a ":" it works fine, so I guess that's the reason.
I couldn't see if ":" is a special character in objectpath, and I couldn't find an escape character to use from the documentation, so a bit stuck. A shame, as it does everything else I need!
The .egg
package format is outdated. The new standard for Python packaging are wheels, see http://pythonwheels.com.
Hi, cool library!
I have a scenario where I want to get all of the "animals" below where the id
attribute contains the word test.
How can I do this? Nothing below seems to work. I can get them explicitly as below, but not from a match this prefix kind of way. The in
and is
comparison operators seems like they should work, but it doesn't appear to.
Python 3.6.4 (default, Mar 15 2018, 16:45:14)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from objectpath import *
>>> x = {
... "a": "test",
... "b": [{
... "animals": [{
... "id": "test AA1",
... "value": "something"
... }, {
... "id": "test AA2",
... "value": "whatever"
... }]
... }]
... }
>>> tree = Tree(x)
>>> result = tree.execute("$.b[0].animals[@.id in 'test AA1']")
>>> next(result)
{'id': 'test AA1', 'value': 'something'}
>>> result = tree.execute("$.b[0].animals[@.id in 'test AA2']")
>>> next(result)
{'id': 'test AA2', 'value': 'whatever'}
>>> result = tree.execute("$.b[0].animals['test' in @.id]")
>>> next(result)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> result = tree.execute("$.b[0].animals[split(@.id,'')[0] is 'test']")
>>> next(result)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
There seems to be no way to utilize the in
or is
syntax in this way? Perhaps I am doing it wrong?
On the start page (i.e. https://adriank.github.io/ObjectPath/), clicking on the tutorial link (i.e. https://adriank.github.io/tutorial.html) results in a 404 ('There isn't a GitHub Pages site here.').
Is there a way to find object with name of structure "**name" / "****name"?
I've tried this by executing $.."**name" and many other combinations on Tree Object but it didn't succeed..
There's such adnotation on documentation page:
Names can be written without quotes, but in that case they cannot start with an operator. ObjectPath raises an exception if name is not valid.
so as far as I understood it shall work with **name (if between quotes)...
If any character is applied before "*" (like " **name" or " %***name") it works.
Thanks and hope there's a quick solution for this problem. ;)
Consider the correctly working code below. It simply selects the elements where x<2
.
>>> a = {"data": [{'x': 1}, {'x':2}]}
>>> tree = objectpath.Tree(a)
>>> list(tree.execute('$.data[@.x < 2]'))
[{'x': 1}]
Now if we remove data
and make the list the root node, it doesn't work:
>>> a = [{'x': 1}, {'x':2}]
>>> tree = objectpath.Tree(a)
>>> list(tree.execute('$[@.x < 2]'))
[{'x': 1}, {'x': 2}]
Is there a reason why this is so? Should it be so? Wouldn't it make conceptual sense to be able to do the same filters on the root node as on child nodes?
Any plan to add 'parent' to JSONPath operators?
(something like parent
in http://jsonpath-rw.readthedocs.org/en/latest/
or ^
in https://github.com/gga/json-path)
In various places you're using sys.version
to determine the Python version. This should use sys.version_info
instead as there is no guarantee that the Python version is always at the beginning of sys.version
.
All the links for docs on the main site giver 404
I think tree=Tree({a:1})
should be tree=Tree({'a':1})
:)
Also I was having troubles with printing tree, getting error like:
>>> tree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/objectpath/core/interpreter.py", line 523, in __repr__
return self.__str__()
File "/usr/local/lib/python2.7/site-packages/objectpath/core/interpreter.py", line 520, in __str__
return "TreeObject(%s)"%str(self.tree)
AttributeError: 'Tree' object has no attribute 'tree'
By default Python's json.load and json.loads creates standard Python dictionaries,
which don't preserve order of keys, so for example the following snippet:
import json, collections
import objectpath
data = """
{
"g1" : { "a" : 1 },
"g2" : { "a" : 2 },
"g3" : { "a" : 3 }
}
"""
tree = objectpath.Tree(json.loads(data))
print "Values of a: ", ",".join(str(x) for x in tree.execute("$..a"))
will print:
Values of a: 3,2,1
This is a problem for me, because for my application that order is important,
I would like to see "1,2,3" printed, as this is the order of values of "a" in my JSON.
So I tried loading data with flag object_pairs_hook = collections.OrderedDict,
which causes json.loads to produce order preserving OrderedDicts:
tree = objectpath.Tree(json.loads(data, object_pairs_hook = collections.OrderedDict))
Unfortunately, if I change the example program like this I get:
Values of a:
Traceback (most recent call last):
File "object_path_bug.py", line 16, in <module>
print "Values of a: ", ",".join(str(x) for x in tree.execute("$..a"))
File "/var/tmp/SKL/lib/python2.7/site-packages/objectpath/core/interpreter.py", line 608, in execute
ret=exe(tree)
File "/var/tmp/SKL/lib/python2.7/site-packages/objectpath/core/interpreter.py", line 288, in exe
fst=flatten(exe(node[1]))
File "/var/tmp/SKL/lib/python2.7/site-packages/objectpath/core/interpreter.py", line 246, in exe
return self.data
AttributeError: 'Tree' object has no attribute 'data'
Would it be possible to fix objetpath so it can work with json data decoded with
object_pairs_hook = collections.OrderedDict, please?
There's no way to check in terminal which version of ObjectPath is installed.
The error looks like this:
Traceback (most recent call last):
File "/usr/local/bin/objectpath", line 11, in
sys.exit(main())
File "/usr/local/lib/python2.7/dist-packages/objectpath/shell.py", line 55, in main
src=open(File,"r")
IOError: [Errno 2] No such file or directory: 'http://hackathon.services-autoscout24.de/id.php?asset=357322040163096'
"%s %s"%["a", "b"] -> "a b"
May be it is just me not understanding something obvious, but why this cannot find a substring in string:
>>> import objectpath
>>> tree = objectpath.Tree({'doc': {'title': 'Purple is Best Color'}})
>>> list(tree.execute('$..*["Purple" in @.title]'))
[]
But, explicitly converting the substring to string with str()
works:
>>> list(tree.execute('$..*[str("Purple") in @.title]'))
[{'title': 'Purple is Best Color'}]
Is this a bug or an intended behavior? Thanks!
SO post for the reference: http://stackoverflow.com/questions/34820888/objectpath-trouble-with-in-operator
Hi,
I've been starting to use ObjectPath earlier today, mostly because I'm dissatisfied with existing JsonPath implementations in Python.
I've been looking through the documentation, but could not find anything related to updating fields from their given path. Is there any functionality like this?
Best regards.
Loading JSON document from http://hackathon.services-autoscout24.de/id.php?asset=357322040163096... done.
$.*
[
{
"latitude": null,
"longitude": null,
"recorded_at": null
},
{
"latitude": 48.14695,
"longitude": 11.5347,
"recorded_at": "2014-10-31T18:25:22Z"
},
{
"latitude": 48.14695,
"GPS_SPEED": {"1": 0},
"longitude": 11.5347,
"recorded_at": "2014-10-31T18:25:21Z"
},
{
"latitude": 48.14775,
"longitude": 11.53441,
"recorded_at": "2014-10-31T18:22:47Z"
},
{
"latitude": 48.14695,
"GPS_DIR": 143.2,
"GPS_SPEED": {"1": 4001},
"longitude": 11.53467,
"recorded_at": "2014-10-31T18:23:03Z"
},
... (11166 more items)
]
$.recorded_at
[
null,
"2014-10-31T18:25:22Z",
"2014-10-31T18:25:21Z",
"2014-10-31T18:22:47Z",
"2014-10-31T18:23:03Z",
... (11166 more items)
]
min($.recorded_at)
min() arg is an empty sequence
Comparing float with null doesn't work
Hi,
I'm trying to parse the following dictionary:
>>> d
{'rpc-reply': {'data': {'groups': {'group': [{'bgp': {'instance': {'instance-as': {'four-byte-as': {'as': '13335', 'bgp-running': '', 'default-vrf': {'global': {'global-afs': {'global-af': {'af-name': 'ipv4-unicast', 'enable': '', 'aggregate-addresses': {'aggregate-address': {'aggregate-prefix': '20', 'route-policy-name': 'anycast-attributes', 'aggregate-addr': '172.17.17.0'}}}}}}}, 'as': '0'}, 'instance-name': 'default'}}, 'group-name': 'GROUP1'}, {'bgp': {'instance': {'instance-as': {'four-byte-as': {'as': '13335', 'bgp-running': '', 'default-vrf': {'global': {'global-afs': {'global-af': {'af-name': 'ipv4-unicast', 'enable': '', 'aggregate-addresses': {'aggregate-address': {'aggregate-prefix': '20', 'route-policy-name': 'anycast-attributes', 'aggregate-addr': '192.168.0.0'}}}}}}}, 'as': '0'}, 'instance-name': 'default'}}, 'group-name': 'GROUP2'}]}}}}
I am able to instantiate the Tree
:
>>> from objectpath import Tree
>>> t = Tree(d)
>>> t
TreeObject()
But I notice that is unable to select:
>>> t.execute("$.rpc-reply")
>>> t.execute("$.data")
When selecting using the square brackets seems that no matter what is requested, returns the whole structure:
>>> t.execute("$['rpc-reply']")
{'rpc-reply': {'data': {'groups': {'group': [{'bgp': {'instance': {'instance-as': {'four-byte-as': {'as': '13335', 'bgp-running': '', 'default-vrf': {'global': {'global-afs': {'global-af': {'af-name': 'ipv4-unicast', 'enable': '', 'aggregate-addresses': {'aggregate-address': {'aggregate-prefix': '20', 'route-policy-name': 'anycast-attributes', 'aggregate-addr': '172.17.17.0'}}}}}}}, 'as': '0'}, 'instance-name': 'default'}}, 'group-name': 'GROUP1'}, {'bgp': {'instance': {'instance-as': {'four-byte-as': {'as': '13335', 'bgp-running': '', 'default-vrf': {'global': {'global-afs': {'global-af': {'af-name': 'ipv4-unicast', 'enable': '', 'aggregate-addresses': {'aggregate-address': {'aggregate-prefix': '20', 'route-policy-name': 'anycast-attributes', 'aggregate-addr': '192.168.0.0'}}}}}}}, 'as': '0'}, 'instance-name': 'default'}}, 'group-name': 'GROUP2'}]}}}}
>>> t.execute("$['anything']")
{'rpc-reply': {'data': {'groups': {'group': [{'bgp': {'instance': {'instance-as': {'four-byte-as': {'as': '13335', 'bgp-running': '', 'default-vrf': {'global': {'global-afs': {'global-af': {'af-name': 'ipv4-unicast', 'enable': '', 'aggregate-addresses': {'aggregate-address': {'aggregate-prefix': '20', 'route-policy-name': 'anycast-attributes', 'aggregate-addr': '172.17.17.0'}}}}}}}, 'as': '0'}, 'instance-name': 'default'}}, 'group-name': 'GROUP1'}, {'bgp': {'instance': {'instance-as': {'four-byte-as': {'as': '13335', 'bgp-running': '', 'default-vrf': {'global': {'global-afs': {'global-af': {'af-name': 'ipv4-unicast', 'enable': '', 'aggregate-addresses': {'aggregate-address': {'aggregate-prefix': '20', 'route-policy-name': 'anycast-attributes', 'aggregate-addr': '192.168.0.0'}}}}}}}, 'as': '0'}, 'instance-name': 'default'}}, 'group-name': 'GROUP2'}]}}}}
Loading the dict into a JSON file and executing form the console:
› objectpath -d groups.json
ObjectPath interactive shell
ctrl+c to exit, documentation at http://adriank.github.io/ObjectPath.
Loading JSON document from groups.json...INFO@35 All strings will be cut to 100 chatacters.
done.
>>> $
START@43 Tree.execute
>>> $.rpc-reply
START@43 Tree.execute
PARSE STAGE
('-', ('.', ('(root)', 'rs'), ('name', 'rpc')), ('name', 'reply'))
START@56 executing node '('-', ('.', ('(root)', 'rs'), ('name', 'rpc')), ('name', 'reply'))'
START@56 executing node '('.', ('(root)', 'rs'), ('name', 'rpc'))'
START@56 executing node '('(root)', 'rs')'
DEBUG@260 . left is '{
'rpc-reply': {u'data': {u'groups': {u'group': [{u'bgp': {u'instance': {u'instance-as': {u'four-byte-as': {u'as': ,
...
}'
START@56 executing node '('name', 'rpc')'
DEBUG@268 . right is 'rpc'
END@277 . returning 'None'
START@56 executing node '('name', 'reply')'
END@609 Tree.execute with: 'None'
null
>>> $['rpc-reply']
START@43 Tree.execute
PARSE STAGE
('(root)',)
START@56 executing node '('(root)',)'
END@609 Tree.execute with: '{
'rpc-reply': {u'data': {u'groups': {u'group': [{u'bgp': {u'instance': {u'instance-as': {u'four-byte-as': {u'as': ,
...
}'
{"rpc-reply": {"data": {"groups": {"group": [
{
"bgp": {...},
"group-name": "GROUP1"
},
{
"bgp": {...},
"group-name": "GROUP2"
}
]}}}}
>>> $['anything']
START@43 Tree.execute
PARSE STAGE
('(root)',)
START@56 executing node '('(root)',)'
END@609 Tree.execute with: '{
'rpc-reply': {u'data': {u'groups': {u'group': [{u'bgp': {u'instance': {u'instance-as': {u'four-byte-as': {u'as': ,
...
}'
{"rpc-reply": {"data": {"groups": {"group": [
{
"bgp": {...},
"group-name": "GROUP2"
},
{
"bgp": {...},
"group-name": "GROUP2"
}
]}}}}
Looks like $.rpc-reply
returns None
, while $['rpc-reply']
returns everything as above.
Is there anything I miss?
Thanks,
Mircea
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.