I have a string containing information in the following format:
Maltese Age: 2 Price: $500
https://images.google/image
Staffy Age: 1 Price: $500
https://images.google/image
Yorkie Age: 2 Price: $300
https://images.google/image
My goal, is to turn the above into something like this:
Dogs:
{
"dog": "Pomeranian",
"info": {
"url": "https://images.google.com/image",
"age": 2,
"price": 1000
}
And of course loop around back and fourth for all of the pets I have in the string.
If you use regular expressions you can get the values like this:
JSONArray arr = new JSONArray();
Matcher m = Pattern.compile("([^ \\r\\n]*) Age: ?(\\d+) Price: ?\\$?(\\d+(?:\\.\\d*)?)\\r?\\n(http[^ \\r\\n]*)").matcher(str);
while (m.find()) {
String dog = m.group(1);
String age = m.group(2);
String price = m.group(3);
String url = m.group(4);
// Add to a JSON object using your preferred JSON library
// Example:
JSONObject obj = new JSONObject();
obj.put("dog",dog);
JSONObject info = new JSONObject();
info.put("age",age);
info.put("price",price);
info.put("url",url);
obj.put("info",info);
arr.put(obj);
}
There are probably multiple ways to do it, but one way to do it may be something as follows.
You can start by splitting your text into lines.
var lines = text.split("\n");
Then you know that odd lines are URLs, and even lines are dog information.
List<JsonObject> objects = new ArrayList<>();
for(int i=0; i < lines.length; i++) {
var line = lines[i];
if(i % 2 == 0) {
// apply regex solution given in the other answer
// to extract the dog information
} else {
url = line;
// since json objects are complete on odd lines
// build json and add it to the list
var jsonObject = ...;
objects.add(jsonObject);
}
}
Related
We have API which gives following responses
[
{
"subject": "English",
"Marks": "79"
},
{
"subject": "Maths",
"Marks": "89"
}
]
We need to validate that
Subject=English and Marks =79
Subject=Maths and Marks =89
we have tried but not successful.
JSONArray jsonarray = new JSONArray(strindentify);
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject jsonobject = jsonarray.getJSONObject(i);
String type = jsonobject.getString("subject");
Assert.assertEquals(type, "English");
String value = jsonobject.getString("Marks");
Assert.assertEquals(value, "79");
System.out.println(" The Subject and Marks:-" +type +"and" +value );
}
Need to assert that Subject=English then Marks=79 etc
There is a problem in your assertion. You have to pass 2 strings to assertEquals:
Assert.assertEquals(type, "English");
Your for loop checks both subjects in each iteration. Instead you will want to get the single values of 'subject' and 'marks' in each iteration, and check your conditions based on the subject.
Such as:
JSONArray jsonarray = new JSONArray(strindentify);
Assert.assertEquals(2, jsonarray.length, "Expected exactly 2 entries in array"); //optional
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject jsonobject = jsonarray.getJSONObject(i);
String type = jsonobject.getString("subject");
String value = jsonobject.getString("Marks");
System.out.println(" The Subject and Marks:-" +type +"and" +value );
switch(type) {
case "English": Assert.assertEquals(value, "79"); break;
case "Maths": Assert.assertEquals(value, "89"); break;
default: throw new RuntimeException("Unexpected subject"); //optional
}
}
Note the '//optional' lines, which respectively will fail the test if there is anything more or less than 2 items in the array, or if any subject other than English or Maths is encountered.
Note that this doesn't fail the edge case where the array contains 2 entries, but both are English or both are Maths.
I used a switch which would allow you to easily add other subjects/marks combinations. An if/else construct would be just as valid. Just remember to break if you use switch!
#Test
public void test_validJson() {
String input = "Your_string_json_here";
JSONArray jsonarray = new JSONArray(input);
Assert.assertNotNull(jsonarray);
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject jsonobject = jsonarray.getJSONObject(i);
Assert.assertNotNull(jsonobject);
String subject = jsonobject.getString("subject");
String value = jsonobject.getString("Marks");
Assert.assertNotNull(subject);
Assert.assertNotNull(value);
switch(subject) {
case "English" :
Assert.assertEquals(value, "79");
break;
case "Maths" :
Assert.assertEquals(value, "89");
break;
default:
// Fail on unrecognized subject?
throw new AssertionException();
}
}
}
Note that this will fail if the subject and/or value is missing and will also fail on unknown subject(s). This makes no guarantees for the length of the array or the ordering of the elements, eg English MUST be the first array item etc. Duplicate subjects will also not fail the test.This simply validates that if given subjects are included in the response then their respective marks are as those given.
Modify this to your liking.
EDIT:
If you want to validate only selected subjects are included:
List<String> knownSubjects = Arrays.asList("History", "Maths", "English", "whatever");
Assert.assertTrue(knownSubjects.contains(subject));
If you want to validate only known subjects WITH known marks:
Map<String, String> subjectMarks = new HashMap<>();
subjectMarks.put("English", "89");
subjectMarks.put("Maths", "79");
subjectMarks.put("Whatever", "10");
Assert.assertTrue(subjectMarks.keySet().contains(subject));
Assert.assertEquals(value, subjectMarks.get(subject));
Good day!
I have an array of json objects like this :
[{
"senderDeviceId":0,
"recipientDeviceId":0,
"gmtTimestamp":0,
"type":0
},
{
"senderDeviceId":0,
"recipientDeviceId":0,
"gmtTimestamp":0,
"type":4
}]
For some reasons I need to split then to each element and save to storage. In the end I have many objects like
{ "senderDeviceId":0,
"recipientDeviceId":0,
"gmtTimestamp":0,
"type":0
}
{
"senderDeviceId":0,
"recipientDeviceId":0,
"gmtTimestamp":0,
"type":4
}
After some time I need to combine some of them back into json array.
As I can see - I can get objects from storage, convert them with Gson to objects, out objects to a list, like this:
String first = "..."; //{"senderDeviceId":0,"recipientDeviceId":0,"gmtTimestamp":0,"type":0}
String second = "...";//{"senderDeviceId":0,"recipientDeviceId":0,"gmtTimestamp":0,"type":4}
BaseMessage msg1 = new Gson().fromJson(first, BaseMessage.class);
BaseMessage msg2 = new Gson().fromJson(second, BaseMessage.class);
List<BaseMessage> bmlist = new ArrayList<>();
bmlist.add(msg1);
bmlist.add(msg2);
//and then Serialize to json
But I guess this is not the best way. Is there any way to combine many json-strings to json array? I rtyed to do this:
JsonElement elementTm = new JsonPrimitive(first);
JsonElement elementAck = new JsonPrimitive(second);
JsonArray arr = new JsonArray();
arr.add(elementAck);
arr.add(elementTm);
But JsonArray gives me escaped string with json - like this -
["{
\"senderDeviceId\":0,
\"recipientDeviceId\":0,
\"gmtTimestamp\":0,
\"type\":4
}","
{
\"senderDeviceId\":0,
\"recipientDeviceId\":0,
\"gmtTimestamp\":0,
\"type\":0
}"]
How can I do this?
Thank you.
At the risk of making things too simple:
String first = "...";
String second = "...";
String result = "[" + String.join(",", first, second) + "]";
Saves you a deserialization/serialization cycle.
I have an array of data sent from my database - Once received, I save it in shared preferences - here is my getter:
public List getAnswerStringEdit() {
return answer_edit;
}
I save it as so:
editor.putString(Constants.ANSWER_EDIT,resp.getAnswer().getAnswerStringEdit().toString().trim());
Then retrieve it here:
String answerString = pref.getString(Constants.ANSWER_EDIT, "").trim();
answerString = answerString.substring(1, answerString.length() - 1).trim();
String[] array = answerString.split(",");
Finally, I access the array as so:
et_answer1_edit.append(array[0]);
My problem is this - Say I add a questions which has a comma in the middle of it, like -
Question 1- "Why is this broke, I don't know?"
Currently, when I retrieve my question, the string is getting split, even though there are quotation marks around the whole question/answer- So in the example above, in position 0 in the array, I should have:
"Why is this broke, I don't know?"
However, instead I am getting in position 0:
Why is this broke - then position 1 as: I don't know
I know this sounds daft because clearly, I am calling for the split to happen on the comma, but I expect that at the end of the whole string object, not in the middle of it.
The retrieved JSON is as follows:
{
"result": "success",
"message": "Answer Has Been Selected",
"answer": {
"answer_edit": ["Why is this broke, I don't know?", "What is your favorite song, because I want to know"]
}
}
Any help/advice that can help me to understand what is causing this, would be really appreciated.
Dont split the string using ',' use this
JSONObject jsonObject = new JSONObject(answerString );
JSONArray jsonArray = jsonObject.getJSONObject("answer").getJSONArray("answer_edit");
Log.e("Json Array elements are","First Element : "+jsonArray.get(0)+"\nSecond Element : "+jsonArray.get(1));
String QuestionString1 = jsonArray.get(0).toString();
String QuestionString2 = jsonArray.get(1).toString();
try this one
JSONObject jsonObject = new JSONObject("your json response");
try
{
JSONObject answer= jsonObject.getJSONObject("answer");
JSONArray jsonArrayAnswerEdit = answer.getJSONArray("answer_edit");
Log.e("=>", "" + jsonArrayAnswerEdit);
for (int i = 0; i < jsonArrayAnswerEdit.length(); i++){
String que= jsonArrayAnswerEdit.getString(i);
Log.e("json", i + "=" + que);
}
} catch (JSONException e) {
e.printStackTrace();
}
Try this
JSONObject jsonObject = new JSONObject("your json response");
try
{
JSONObject data = jsonObject.getJSONObject("answer");
JSONArray jsonArray = data.getJSONArray("answer_edit");
Log.e("=>", "" + jsonArray);
for (int i = 0; i < jsonArray.length(); i++)
{
String value = jsonArray.getString(i);
String[] parts = value.split(Pattern.quote(","));
for (int j=0; j<parts.length; j++)
{
Log.e("Answer String ", "=" + parts[j]);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
OUTPUT
E/=>: ["Why is this broke, I don't know?","What is your favorite song, because I want to know"]
E/Answer String: =Why is this broke
E/Answer String: = I don't know?
E/Answer String: =What is your favorite song
E/Answer String: = because I want to know
After reading all the suggest answers, figured out a simple solution:
First I stored my answers sent from my external database as so -
final String jsonAnswers = gson.toJson (resp.getAnswer().getAnswerStringEdit());
Then saved in shared pref -
editor.putString(Constants.ANSWER_EDIT,jsonAnswers);
Next to read the answer back out:
String answerString = pref.getString(Constants.ANSWER_EDIT, "").trim();
final String[] array = gson.fromJson (answerString, String[].class);
Finally, I could set my Edittext with data from the array:
et_answer1_edit.append(array[0].trim());
et_answer2_edit.append(array[1].trim());
I am not able to format below string :
"Sony,20,30,40;LG,1,4,8"
In below JSON format:
"reported": {
"SETS": [
{
"prodName": "Sony",
"fmtd": "20",
"lmtd": "30",
"lm": "40"
},
{
"prodName": "LG",
"mtd": "1",
"lmtd": "4",
"lm": "8"
}
]
}
I tried below code but not getting proper results.
String stringFromProc = "SONY,20,30,40;LG,1,4,8";
String[] array1 = stringFromProc.split("[\\;]");
JSONObject jsonSubObject = null;
JSONObject jsonFinal = new JSONObject();
JSONArray jsonArrayRET = new JSONArray();
for(int i=0;i<array1.length;i++){
String []array2 = array1[i].split("[\\,]");
for(int j=0;j<array2.length;j++){
System.out.println(array2[j]);
jsonSubObject = new JSONObject();
jsonSubObject.put("prodName", array2[0]);
jsonSubObject.put("mtd", array2[1]);
jsonSubObject.put("lmtd", array2[2]);
jsonSubObject.put("lm", array2[3]);
jsonArrayRET.add(jsonSubObject);
jsonFinal.put("reported", jsonArrayRET);
}
}
But getting this format:
{"SETS":[{"lm":"40","lmtd":"30","mtd":"20","prodName":"MNP"},{"lm":"40","lmtd":"30","mtd":"20","kpiName":"MNP"},{"lm":"40","lmtd":"30","mtd":"20","kpiName":"MNP"},{"lm":"40","lmtd":"30","mtd":"20","kpiName":"MNP"},]}
I know that I am making loop after splitting the comma separated array but not able to get the correct approach of how to split. Someone please suggest.
Just remove the internal loop
String stringFromProc = "SONY,20,30,40;LG,1,4,8";
String[] array1 = stringFromProc.split(";"); // simply use ;
// array1[0] = SONY,20,30,40
// array1[1] = LG,1,4,8
JSONObject jsonSubObject = null;
JSONObject jsonFinal = new JSONObject();
JSONArray jsonArrayRET = new JSONArray();
for(int i=0;i<array1.length;i++){
String []array2 = array1[i].split(","); // simply use ,
// create jsonobjects
// when i=0 mean for sony and next time i = 1 mean for LG
jsonSubObject = new JSONObject();
jsonSubObject.put("prodName", array2[0]);
jsonSubObject.put("mtd", array2[1]);
jsonSubObject.put("lmtd", array2[2]);
jsonSubObject.put("lm", array2[3]);
// put every object in array
jsonArrayRET.add(jsonSubObject);
}
// finally put array in reported jsonobject
jsonFinal.put("reported", jsonArrayRET);
Note : ; and , are not special regular expressions characters so no escaping \\ is required and instead of long info just read about character class []
Move
jsonFinal.put("reported", jsonArrayRET);
outside of 2nd loop, you are overwritting reported object.
for(int i=0;i<array1.length;i++){
String []array2 = array1[i].split("[\\,]");
for(int j=0;j<array2.length;j++){
System.out.println(array2[j]);
jsonSubObject = new JSONObject();
jsonSubObject.put("prodName", array2[0]);
jsonSubObject.put("mtd", array2[1]);
jsonSubObject.put("lmtd", array2[2]);
jsonSubObject.put("lm", array2[3]);
jsonArrayRET.add(jsonSubObject);
}
jsonFinal.put("reported", jsonArrayRET);
}
I have a string I would like to put into an ArrayList of Strings. The string is basically a JSONObject so I might just be using the wrong methods.
The way the string looks is:
String all = "{"users":
[
[{"login":"username1"},{"password":"test1"},{"index":"1"}],
[{"login":"username2"},{"password":"test2"},{"index":"2"}]
]}";
All I want is the JSONObject values so my pattern gives me this String:
String part = "[
[{"login":"username1"},{"password":"test1"},{"index":"1"}],
[{"login":"username2"},{"password":"test2"},{"index":"2"}]
]";
This is what I want:
user[0] = "[{"login":"username1"},{"password":"test1"},{"index":"1"}]";
user[1] = "[{"login":"username2"},{"password":"test2"},{"index":"2"}]";
When I try to group everything in between the inner [ ] it just returns everything in the outer [ ].
I have tried:
String[] user = new String[20];
Pattern p = Pattern.compile("(\\[\\{.*\\}\\])");
Matcher m = p.matcher(part);
while(m.find()){
user = m.group().split("\\],\\[");
}
This approach gets rid of the ],[ which I'm using as a delimiter.
Class User {
private String username;
private String password;
}
Class Users{
LinkedList<User> users;
}
You can use any available JSON marshallers like Jackson etc to deserialize the string into a Users.
So I took the advice from the comment section and sure enough using JSON methods was the way to go. I would still like to see if it was possible to accomplish with regular expressions.
ArrayList<String> myList = new ArrayList<String>();
JSONObject obj = new JSONObject();
JSONArray arr = new JSONArray();
obj = {"user":"[[{},{},{}],[{},{},{}]]";
// This gives me the outer JSONArray
arr = obj.getJSONArray("user");
// This iterates through the outer JSONArray assigning each inner JSONArray
// to my ArrayList as strings.
for( int i = 0; i < arr.length(); i++){
myList.put(arr.getJSONArray(i).toString());
}