Unable to get value of key with spaces using JsonPath library - java

I'm using Json Path library to parse JSON. I've following json which has key with space:
{
"attributes": {
"First Name": "Jim",
"Last Name": "Rohn"
}
}
In order to get value of First Name, I wrote code like (where json is object which holds above json) -
String firstName = JsonPath.from(json).getString("attributes.First Name");
But it results into following error -
java.lang.IllegalArgumentException: Invalid JSON expression:
Script1.groovy: 1: expecting EOF, found 'Attributes' # line 1, column 67.
.First Name
Could you please suggest how to get values of key having spaces using json-path library?

Try using bracket notation for First Name as follows:
String firstName = JsonPath.from(json).getString("attributes.['First Name']");
UPDATE
Sorry for mixing different JsoPath libraries up.
If you are using com.jayway.jsonpath, try following way for escaping:
DocumentContext jsonContext = JsonPath.parse(json);
String firstName = jsonContext.read("$.attributes.['First Name']");
But if you are using ***.restassured.json-path, please use this one:
String firstName = JsonPath.from(json).getString("attributes.'First Name'");

You have to escape the key with single quotes
Use below code:
String firstName = JsonPath.from(json).getString("'attributes.First Name'");

If you are using io.restassured.path.json.JsonPath library then Escape Sequences is required in the path expression.
String firstName = JsonPath.from(json).getString("attributes.\"First Name\"");
\" <-- Insert a double quote character in the text at this point.
So your path expression looks like (attributes."First Name") and can be parsed by JsonPath library

Related

RedisGraph: how to persist properties in data containing BOTH single AND double quotes?

I am testing RedisGraph as a way to store my data which originates from a client as JSON.
The JSON passes through a bean for validation etc and I use Jackson to serialise the bean so the RedisGraph string is in the correct format. For completeness on that formatting step see the sample code at the end.
The data properties might contain sinqle quotes in valid JSON format eg: O'Toole
{ "name" : "Peter O'Toole", "desc" : "An actors actor" }
I can use a formatter as per the code block at the end to get the JSON into a format the RedisGraph command will allow which copes with the single quotes (without me needing to escape the data content - ie it can use what the client sends). eg this works:
GRAPH.QUERY movies "CREATE (:Actor {name:\"Peter O'Toole\", desc:\"An actors actor\", actor_id:1})"
So far, so good.
Now, the problem: I am having trouble with the syntax to persist original JSON where it ALSO contains escaped double quotes. eg:
{ "name" : "Peter O'Toole", "desc" : "An \"actors\" actor" }
I don't want to have to escape or wrap the desc property value because it is already escaped as valid JSON. But then how do I construct the RedisGraph command so it persists the properties using the values it is given? ie containing escaped double quotes.
In other words, this throws a parsing error because of the \" in the desc property.
GRAPH.QUERY movies "CREATE (:Actor {name:\"Peter O'Toole\", desc:\"An \"actors\" actor\", actor_id:1})"
Given it would be quite common to want to persist data containing valid JSON escaped double quotes \" AND unescaped single quotes, there must be a way to do this. eg name and address data.
Any ideas?
Thanks, Murray.
PS: this doesnt work either: it chokes on the embedded ' in O'Toole
GRAPH.QUERY movies "CREATE (:Actor {name:\'Peter O'Toole\', desc:\'an \"actors\" actor\', actor_id:3})"
// \u007F is the "delete" character.
// This is the highest char value Jackson allows and is
// unlikely to be in the JSON (hopefully!)
JsonFactory builder = new JsonFactoryBuilder().quoteChar('\u007F').build();
ObjectMapper objectMapper = new ObjectMapper(builder);
// Set pretty printing of json
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// Do not surround property names with quotes. ie { firstName : "Peter" }
objectMapper.configure(JsonWriteFeature.QUOTE_FIELD_NAMES.mappedFeature(), false);
// Make a Person
Person person = new Person("Peter", "O'Toole");
// Set the desc property using embedded quotes
person.setDesc("An \"actors\" actor");
// Convert Person to JSON
String json = objectMapper.writeValueAsString(person);
// Now convert your json to escape the double quotes around the string properties:
String j2 = json.replaceAll("\u007F", "\\\\\"");
System.out.println(j2);
This yields:
{
firstName : \"Peter\",
lastName : \"O'Toole\",
desc : \"An \"actors\" actor\"
}
which is in a format Redis GRAPH.QUERY movies "CREATE..." can use (apart from the issue with \"actors\" as discussed above).
OK. The issue was an artefact of trying to test the syntax by entering the commands into RedisInsight directly. As it turns out all one needs to do is to remove the double quotes from the valid json.
So, to be clear, based on normal valid json coming from the client app,
the formatter test is:
ObjectMapper objectMapper = new ObjectMapper();
// (Optional) Set pretty printing of json
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// Do not surround property names with quotes. ie { firstname : "Peter" }
objectMapper.configure(JsonWriteFeature.QUOTE_FIELD_NAMES.mappedFeature(), false);
// Make a Person
// For this example this is done directly,
// although in the Java this is done using
// objectMapper.readValue(incomingJson, Person.class)
Person person = new Person("Peter", "O'Toole");
// Set the desc property using escaped double quotes
person.setDesc("An \"actor's\" actor");
// Convert Person to JSON without quoted property names
String json = objectMapper.writeValueAsString(person);
System.out.println(json);
yields:
{
firstname : "Peter",
lastname : "O'Toole",
desc : "An \"actor's\" actor"
}
and the command string is consumed by the Vertx Redis:
Vertx vertx = Vertx.vertx();
private final Redis redisClient;
// ...
redisClient = Redis.createClient(vertx);
String cmdStr = "CREATE (:Actor {firstname:"Peter", lastname: "O'Toole", desc:"An \"actor's\" actor", actor_id:1})";
Future<String> futureResponse = redisClient.send(Request.cmd(Command.GRAPH_QUERY).arg("movies").arg(cmdStr))
.compose(response -> {
Log.info("createRequest response=" + response.toString());
return Future.succeededFuture("OK");
})
.onFailure(failure -> {
Log.error("createRequest failure=" + failure.toString());
});
:-)

Using rest-assured get value using path method

I want to extract value of s.d.url from the below JSON.
I am using the below satement as shown using System.out.println
but I dont get the result. How do I do it when the field itself contains "."
JSON
{
"data":{
"H1":{
"com.abc.def":{
"a_enabled":false,
"b_config":true
},
"c.s.urls":{
"s.d.url":"https://url1.com",
"w.p.url":"https://url2.com",
"s.c.url":"https://url3.com"
},
"com.abc.con":{
"e_n":true,
"a_r":false,
"c_t":"XYZMB"
}
},
"dCId":"ABCD"
}
}
ExtractableResponse<Response> spec = given()
.request().log().all()
.expect().statusCode(200)
.when()
.get(EndpointsCloudServices.getConfigUrl() + "?" + params)
.then().log().body()
.extract();
//want to get value of s.d.url
System.out.println("Triage???? " + spec.path("data.H1.c.s.urls.s.d.url"));
Give a try for the following, it will return value of s.d.url (pay attention for square brackets and single quotes):
spec.path("data.H1.['c.s.urls'].['s.d.url']")
or even shorter, if you're sure that s.d.url is an unique name across the whole json document:
spec.path("$.['s.d.url']")
And next, this is just to illustrate common case of referring field which contains dots in its name by using JSONPath expression - all you need is to wrap the field name in [' and ']
Example JSON:
{
"field.name": "value",
"nested": {
"field.with.dot": {
"field.inside": "anotherValue"
}
}
}
Example valid JSONPath expressions to access corresponding field values:
$['field.name']
$.['field.inside']
nested.['field.with.dot'].['field.inside']
Hint: you can quickly test your JSONPaths agains your json using tools like online evaluator or expression tester

Trying to write quotes (") in xml using java

I have a long string which contains ~" & "~ etc.
but when I am trying to write it in xml the o/p is: ~&quot
please suggest a way to write the complete string including "(double quotes)
Below are my code:
for(String str:Parser.queryList){
Element query = doc.createElement("query");
view.appendChild(screen);
screen.appendChild(query);
query.setAttribute("query", str);
}
output: OP =~"=~"

Android - decode unicode characters without StringEscapeUtils?

When I use Gson (JsonParser.parse) to decode the following:
{ "item": "Bread", "cost": {"currency": "\u0024", "amount": "3"}, "description": "This is bread\u2122. \u00A92015" }
The "currency" element is returned as a string of characters (and is not converted to a unicode character). Is there a setting or method in Gson that could help me?
If not, is there any way in Android to convert a string that contains one or more escaped character sequences (like "\u0024") to an output string with unicode characters (without writing my own and without using StringEscapeUtils from Apache)?
I'd like to avoid adding another library (for just one small feature).
Update
Looks like the server was double escaping the back slash in the unicode escape sequence. Thanks everyone for your help!
Is it only me or is it really more complicated than simply using TextView's setText() method? Anyhow, following is working just fine on my end with the given sample json (put the sample to assets and read it using loadJSONFromAsset()):
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(loadJSONFromAsset());
JsonObject obj = element.getAsJsonObject();
JsonObject cost = obj.getAsJsonObject("cost");
JsonPrimitive sign = cost.get("currency").getAsJsonPrimitive();
TextView tv = (TextView)findViewById(R.id.dollar_sign);
tv.setText(sign.getAsString());
Gson returns "$". Something is wrong in your set up.
String s = "{ \"item\": \"Bread\", \"cost\": {\"currency\": "
+ "\"\\u0024\", \"amount\": \"3\"}, \"description\": "
+ "\"This is bread\\u2122. \\u00A92015\" }\n";
JsonElement v = new JsonParser().parse(s);
assertEquals("$", v.getAsJsonObject().get("cost").getAsJsonObject()
.get("currency").getAsString());
You can parse it as a hex number
char c = (char)Integer.parseInt(str.substring(2), 16);

Parsing a JSON Object in Java having special characters

I am stuck in a situation, where my JSONString (ruleFormJSONString) looks like :
{
"ruleDescription":"Test Rule2 Description",
"urlId":"1",
"listOfBusinessdays":["1","2","5","6","7"],
"status":"1",
"hierarchyId":"3",
"fromTime":"08:00",
"toTime":"18:00",
"dcnid":"1",
"eventId":"1",
"rowstate":"1",
"listOfLocations":["ASM","DEL"],
"ruleName":"Test Rule2",
"ruleId":"7","msgId":"1"
}
As you can see there are 2 attributes named fromTime and toTime which has a :
So while parsing this in Java, I used
JSONObject ruleFormJSON = JSONObject.fromString(ruleFormJSONString);
String fromTime = (String)ruleFormJSON.getString("fromTime");
String toTime = (String)ruleFormJSON.getString("toTime");
I am getting a NumberFormatException which is
java.lang.NumberFormatException: For input string: "18:00"
So please suggest me how, to get the value in the corresponding String variable.
Any help will be appreciated.
It seems there is an error on this line:
"listOfBusinessdays":"1","2","5","6","7"],
A closed bracket square but no open bracket before.
May be this hang up the parser.

Categories