I've been spending the last couple of days trying to format a JSON string into a JSON object, but this is not quite the usual json string. Im receiving it from an url and have no problem converting it into a string but when im going to create the JSON object Ive found a whole lot of issues.
The JSON looks like this:
header {
gtfs_realtime_version: "1.0"
incrementality: FULL_DATASET
timestamp: 1511789066
}
entity {
id: "294-131-39-562-4732025"
vehicle {
trip {
trip_id: "131-39-562-4732025"
route_id: "131"
}
position {
latitude: 3.44351
longitude: -76.52622
}
timestamp: 1511789065
stop_id: "501450"
vehicle {
id: "21002"
label: "MC21002"
license_plate: "VCQ452"
}
}
}
entity {
id: "1087-431-55-35-4732025"
vehicle {
trip {
trip_id: "431-55-35-4732025"
route_id: "431"
}
position {
latitude: 3.3767517
longitude: -76.54276
}
timestamp: 1511789065
stop_id: "502150"
vehicle {
id: "31038"
label: "MC31038"
}
}
}
as you can see there is no array, nor commas separating the element that I need to process (entity), I cant even get the JSONObject from the root.
Any suggestions?
This is the last block of code I've tried in which I remove the header, insert all the entity objects into the array buses, and separate them by commas, but is no use
//getRespuesta(); gives me the string
//Log.d("LIVE", "RAW JSon: " + getRespuesta());
String[] parts = getRespuesta().split("[}]", 2);
String[] splitter = parts[1].split("(?=entity)");
String finalString = splitter[1];
for (int t = 2; t < splitter.length; t++) {
finalString = finalString + ",\n" + splitter[t];
}
Log.d("LIVEL", "SIZE: " + splitter[1]);
String JSonChunk = "{ \n \"buses\": [ \n " + finalString + "\n ] \n }";
//String JSonChunk = "{ \n " + parts[1] + "\n }";
try {
// Log.d("LIVE", "CHUNKED JSon: " + JSonChunk);
JSONObject json = new JSONObject(JSonChunk);
}catch........
As was mentioned in the comments and as you've seen you can't use a JSON parser on non-JSON. I'd take the following approach:
If this meets the specifications of a known format, someone has probably written a JSON converter you can run it through.
If it is a custom format but each line is a predictable format and does not rely on anything before or after, you can run each line through a custom converter and give it the 'JSON-ness.' (add commas, etc) Process each line at at time rather than trying to split up the whole thing at once.
If none of the above are true, you need to go into regular expression hell. Sorry :(
From my point of view you must transform it to a valid JSON String
You can try this regex:
https://regex101.com/r/15dHwd/1
That means, for each group that capture tou replace it with ": {"
That way: "position {" will re replaced with "position: {"
Now you have other issue,
"entity" appears twice
If you are 100% sure that you will get always that format, after the first replace:
Start with appending "{" on the beginning of the string
Get a regex to find the "entity" String
Replace the first match with "array: [ entity"
List item
On the end of the string append: "]}"
Related
Here is an example of a String:
val message = "Customer name is $name saved on $date"
I needed to find every instance of $variable within the string message and replace it with querySnapShot.get(variable) and that has been answered here Previous Answer. querySnapShot here just contains data from within Firestore listener.
Here is the working Kotlin code:
val message = "Customer name is $name saved on $date"
val arr = message.split(" ").toTypedArray()
for (i in 0 until arr.size) {
val s = arr[i]
if (s.contains("$")) {
arr[i] = "+ querySnapshot.get(" + "\"" + s.substring(1) + "\"" + ")"
}
}
Log.d("Mate", java.lang.String.join(" ", *arr))
which prints:
customer name is querySnapShot.get("name") saved on querySnapshot.get("data)
literally as it is.
QUESTION:
How can I add Kotlin's expression ${} correctly while splitting and joining in order for it to treat querySnapshot.get("variable") as an expression that captures and returns dynamic data after joining? And not just a mere String.
Write
arr[i] = querySnapshot.get(s.substring(1))
The solution isn't to try to use Kotlin string templating, it's to stop putting your own code in strings when you want to run it instead!
I am trying to bind JSON to Java POJO class using com.google.gson.Gson
like this :
MyClass data = gson.fromJson(jsonString, MyClass.class);
When I am using below mentioned it's working fine
{
"data": "{\"key1\":{\"key11\":\"192.192.1.192\",\"key12\":\"WEB\"}}"
}
However, when below-mentioned data is used, I am getting MalformedJsonException
{
"data": "{"key1":{"key11":"192.168.1.158","key12":"WEB"}}"
}
Log :
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException:
Unterminated object at line 1 column 354 path
You can not use " within a String to quote your JSON keys and values. You either have to escape them (like you did in your first example) or you have use single quotes '.
You are effectively trying to do String concatenation without using +.
This looks for the compiler like a list of Strings with variables in between:
"{"key1":{"key11":"192.168.1.158","key12":"WEB"}}"
The compiler would expect something like this:
"{" + key1 + ":{" + key11 + ":" + 192.168.1.158 + "," + key12 + ":" + WEB + "}}";
If you look at the String this way you immediately see the problem. That's why you should either escape the quotes or use single quotes:
"{\"key1\":{\"key11\":\"192.168.1.158\",\"key12\":\"WEB\"}}"
"{'key1':{'key11':'192.168.1.158','key12':'WEB'}}"
I am using Katalon studio to send an HTTP request. Before I send the request I would like to edit the body of the JSON object.
JSON - Body
{
"properties":{},
"routing_key":"actions.process.x.1",
"payload": "{
\"type\":\"SEND_TWEET\",
\"twitterAccessTokens\":{
\"token\":\"abzzzzzzzzzUS38IHg3wvT7fhd63hdh3y4hfhfjr3433rcI\",
\"secret\":\"abzzzzzzzzzUS38IHg3wvT7fhd63hdh3y4hfhfjr3433rcI\"
},
\"screenName\":\"D123\",
\"text\":\" #automation_br test test test 111\"
}",
"payload_encoding":"string"
}
When sending the request without editing the body: The correct JSON is printed
def originalBody = request.getHttpBody()
System.out.println('O_Body: ' + originalBody)
Response: Start action : Statement - out.println("O_Body: " + originalBody)
{
"properties":{},
"routing_key":"actions.process.x.1",
"payload": "{
\"type\":\"SEND_TWEET\",
\"twitterAccessTokens\":{
\"token\":\"abzzzzzzzzzUS38IHg3wvT7fhd63hdh3y4hfhfjr3433rcI\",
\"secret\":\"abzzzzzzzzzUS38IHg3wvT7fhd63hdh3y4hfhfjr3433rcI\"
},
\"screenName\":\"D123\",
\"text\":\"hello test test test 1 2 3\"
}",
"payload_encoding":"string"
}
When I edit the http body and try to add my own escaped string with an added variable that gets generated I get the following output:
//String
String Body = '{\n "properties":{},\n"routing_key":"actions.process.x.1",\n"payload":"{\n \\"type\\":\\"SEND_TWEET\\" ,\n \\"twitterAccessTokens\\":{\n \\"token\\":\\"845259605840183297-O0RYViNU5mCt0WutyWdo4URGyiQLMjI\\",\n \\"secret\\":\\"78Qy1FQ26YEHMpSiMEUS38IHg3wvTLdDhwdDy0kF55rcI\\" \n },\n \\"screenName\\":\\"Deane56935078\\",\n \\"text\\":\\"#Deane56935078 #automation_br ' + randomString + ' \n}",\n "payload_encoding":"string" \n}'
System.out.println('Body: ' + Body)
//Change HTTP Body
request.setHttpBody(Body)
Output:
"{
"properties":{},
"routing_key":"actions.process.x.1",
"payload":"{
\"type\":\"SEND_TWEET\" ,
\"twitterAccessTokens\":{
\"token\":\"845259605840183297-O0RYViNU5mCt0WutyWdo4URGyiQLMjI\",
\"secret\":\"78Qy1FQ26YEHMpSiMEUS38IHg3wvTLdDhwdDy0kF55rcI\"
},
\"screenName\":\"Deane56935078\",
\"text\":\"#Deane56935078 #automation_br " + randomString + "
}",
"payload_encoding":"string"
}"
after editing the body the JSON has inverted commas at the beginning and end. The random string value does not get printed instead it prints the name.
Could anyone please help with the escape of characters when using JSONin a string?
You can create a custom keyword to escape string so that you can use it across test case. This topic has the function you need , or use jettison
When used in test case, you need to replace
\”text\”:\”#Deane56935078 #automation_br " + randomString + "
with
Customkeywords.quote("#Deane56935078 #automation_br " + randomString);
Here are some lines from a file and I'm not sure how to parse it to extract 4 pieces of information.
11::American President, The (1995)::Comedy|Drama|Romance
12::Dracula: Dead and Loving It (1995)::Comedy|Horror
13::Balto (1995)::Animation|Children's
14::Nixon (1995)::Drama
I would like to get the number, title, release date and genre.
Genre has multiple genres so I would like to save each one in a variable as well.
I'm using the .split("::|\\|"); method to parse it but I'm not able to parse out the release date.
Can anyone help me!
The easiest would be matching by regex, something like this
String x = "11::Title (2016)::Category";
Pattern p = Pattern.compile("^([0-9]+)::([a-zA-Z ]+)\\(([0-9]{4})\\)::([a-zA-Z]+)$");
Matcher m = p.matcher(x);
if (m.find()) {
System.out.println("Number: " + m.group(1) + " Title: " + m.group(2) + " Year: " + m.group(3) + " Categories: " + m.group(4));
}
(please don't nail me on the exact syntax, just out of my head)
Then first capture will be the number, the second will be the name, the third is the year and the fourth is the set of categories, which you may then split by '|'.
You may need to adjust the valid characters for title and categories, but you should get the idea.
If you have multiple lines, split them into an ArrayList first and treat each one separately in a loop.
Try this
String[] s = {
"11::American President, The (1995)::Comedy|Drama|Romance",
"12::Dracula: Dead and Loving It (1995)::Comedy|Horror",
"13::Balto (1995)::Animation|Children's",
"14::Nixon (1995)::Drama",
};
for (String e : s) {
String[] infos = e.split("::|\\s*\\(|\\)::");
String number = infos[0];
String title = infos[1];
String releaseDate = infos[2];
String[] genres = infos[3].split("\\|");
System.out.printf("number=%s title=%s releaseDate=%s genres=%s%n",
number, title, releaseDate, Arrays.toString(genres));
}
output
number=11 title=American President, The releaseDate=1995 genres=[Comedy, Drama, Romance]
number=12 title=Dracula: Dead and Loving It releaseDate=1995 genres=[Comedy, Horror]
number=13 title=Balto releaseDate=1995 genres=[Animation, Children's]
number=14 title=Nixon releaseDate=1995 genres=[Drama]
I'm using a combination of Java Play Framework, MongoDB and Jongo as my go between for a basic web CRUD app. I keep receiving a JSON parse exception even though my string doesn't contain any illegal characters. It's actually failing on closing curly bracket at the end of the statement. Below is my error and code. The query string is just a string builder, searching if an object is empty or has a value, if it has a value it's appended to a string.
Jongo method:
public static Iterable<OneDomain> findWithQueryString(String queryString){
return domains().find("{#}", queryString).as(OneDomain.class);
}
Controller Methods:
String builder example:
if(queryStringBuilder.toString().equalsIgnoreCase("")){
queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
}else{
queryStringBuilder.append(" , ");
queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
}
String queryString = queryStringBuilder.toString();
Iterable<OneDomain> filteredIterable = OneDomain.findWithQueryString(queryString);
Gives me this error:
Caused by: com.mongodb.util.JSONParseException:
{"source : Online Lists , blacklist : true , vetted : true , is : false , isNot : true"}
^
with the error on the "}" ending it.
In addition to that, if I try to escape the characters by putting in a \" so it becomes \"date\" it will parse and error out like so:
Caused by: com.mongodb.util.JSONParseException:
{"\"source\" : \"Online Lists\" , \"blacklist\" : true , \"vetted\" : true , \"is\" : false , \"isNot\" : true"}
You're building JSON by hand, and doing it wrong. You need to learn the basic JSON syntax requirements
A basic JSON-encoded object is
{"key1":"value1","key2":"value with \" escaped internal quote"}
Note all of the quotes. Your json string is a single very long object key with no associated value, which is not permitted. All keys must have values.