Reputation: 245
Could you please recommend how to use JsonPath in the Robot Framework? It should supports multi-level query as following:
$.items[?(@.status.name="closed")].name
I'm seeking the way to make following work:
*** Variables ***
${json} {"items":[{"name":"item1","status":{"id":1,"name":"opened"}},{"name":"item2","status":{"id":2,"name":"closed"}}]}
${json_path} $.items[?(@.status.name="closed")].name
*** Test Cases ***
Get closed item
${names}= Get Json Items ${json} ${json_path}
Should be equal ${names[0]} item2
someting like this
Upvotes: 1
Views: 5275
Reputation: 1582
This RF code does what you need but ONLY for provided json structure. From my point of view you should play with Get Json Value
and prepare keywords you need. BTW, it is obvious that such json/string handling in RF is a bit complicated so I would rather write small Python library with keywords you need.
*** Settings ***
Library Collections
Library HttpLibrary.HTTP
*** Variables ***
${json} {"items":[{"name":"item1","status":{"id":1,"name":"opened"}},{"name":"item2","status":{"id":2,"name":"closed"}}]}
${name} ${EMPTY}
${result} ${EMPTY}
*** Test Cases ***
Get Closed Item
${name} Get Name By Status ${json} closed
Should Be Equal As Strings ${name} item2
${name} Get Name By Status ${json} opened
Should Be Equal As Strings ${name} item1
*** Keywords ***
Get Name By Status
[Arguments] ${json} ${status}
[Return] ${result}
${json} Parse Json ${json}
:FOR ${item} IN @{json["items"]}
\ ${item} Stringify Json ${item}
\ ${name} Get Json Value ${item} /name
\ ${name} Parse Json ${name}
\ ${status_name} Get Json Value ${item} /status/name
\ ${status_name} Parse Json ${status_name}
\ ${result} Set Variable If '${status_name}' == '${status}' ${name} ${result}
Edit: based on comment below I would go for such python based code.
JsonpathLibrary.py
:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import json
import jsonpath
class JsonpathLibrary(object):
def get_items_by_path(self, json_string, json_path):
json_object = json.loads(json_string)
match_object = jsonpath.jsonpath(json_object, json_path)
match_string = json.dumps(match_object[0])
return match_string
RF code:
*** Settings ***
Library JsonpathLibrary.py
*** Variables ***
${json} {"items":[{"name":"item1","status":{"id":1,"name":"opened"}},{"name":"item2","status":{"id":2,"name":"closed"}}]}
${json_path} $.items[?(@.status.name=="closed")].name
*** Test Cases ***
Some Descriptive Name Here
${name} Get Items By Path ${json} ${json_path}
Should Be Equal As Strings ${name} "item2"
Upvotes: 1