How to parse nested json arrays in a single object in android - java
I have a json which has a number of nested JSONARRAY. here is the snippet.
{
"location": [
{
"name": "Perth",
"conferencelocation": [
{
"locationname":"Stage 1" ,
"guests": [
{
"guestid":"4074513426041094",
"guestname":"Keegan Connor Tracy",
"time":"9am",
"largeimg":"http://ozcomiccon.com/images/banner/Keegan.jpg",
"smallimg":"http://ozcomiccon.com/images/banner/Keeganresized.jpg",
"biotext": "Born in Windsor, Ontario, Canada, Tracy attended Wilfrid Laurier University in Waterloo, Ontario, Canada, where she orginally studied business. She later switched to psychology. She spent a year in Europe working in Dublin, Paris and Nice, where she was supposed to be completing her 4th year of study. She later returned to WLU to finish her degree. She moved to Vancouver, B.C. where she has had all of her acting jobs.",
"autographs":"$30 each (an 8x10 photograph will be included with each signature, or you may choose to have an appropriate personal item signed).",
"photographs":"Photo with Keegan $40.",
"genre":"acting",
"links": [
{"linkname":"Twitter", "url":"https://twitter.com/keegolicious" },
{"linkname":"IMDB", "url":"http://www.imdb.com/name/nm0870535/" }
]
},
{
"guestid":"1054713366041913",
"guestname":"Matthew Clark",
"time":"10am",
"largeimg":"http://ozcomiccon.com/images/banner/matthewclark.jpg",
"smallimg":"http://ozcomiccon.com/images/banner/matthewclarkresized.jpg",
"biotext": "Matthew Clark is a comic book artist living and working in Portland, Oregon. Having worked on art of some of the most well-known DC characters in comic book history, he recently did pencils for DC’s latest version of the Doom Patrol. Matthew is currently working on Ghost Rider for Marvel Comics, with whom he has signed an exclusive two-year deal.<br /><br />Matthew has lived in Portland for the past 13 years, just above an art gallery in the heart of downtown. He loves to walk around this fair city (mainly because he sold his car and needed to force himself to exercise). He’s a native Oregonian and that’s saying something. For the past 11 years he’s met Greg Rucka for coffee every Wednesday pretty much without fail at the same place (we pretty much carved our names in the table). Matthew was also one of the original founders of Mercury Studio (now Periscope Studio); he got his start at Studiosaurus.<br /><br />He still reads comics, loves what he does, and works very hard. Loves to meet new people, but is really quiet (and has great hair).",
"autographs":"Complimentary at guest's discretion.(Twitter)",
"photographs":"",
"genre":"comic",
"links": [
{"linkname":"Website", "url":"http://www.matthewclarkartist.com/" },
{"linkname":"Twitter", "url":"https://twitter.com/emceeartist" }
]
}
]
},
{
"locationname":"Stage 2" ,
"guests": [
{
"guestid":"106146633306036834",
"guestname":"Sean Williams",
"time":"8am",
"largeimg":"http://ozcomiccon.com/images/banner/seanwilliams.jpg",
"smallimg":"http://ozcomiccon.com/images/banner/seanwilliamsresized.jpg",
"biotext": "Sean Williams was born in the dry, flat lands of South Australia, where he still lives with his wife and family. He has been called many things in his time, including “the premier Australian speculative fiction writer of the age†(Aurealis), the “Emperor of Sci-Fi†(Adelaide Advertiser), and the “King of Chameleons†(Australian Book Review) for the diversity of his output. That award-winning output includes thirty-five novels for readers all ages, seventy-five short stories across numerous genres, the odd published poem, and even a sci-fi musical.<br /><br />He is a multiple recipient of the Aurealis and Ditmar Awards in multiple categories and has been nominated for the Philip K. Dick Award, the Seiun Award, and the William Atheling Jr. Award for criticism. He received the “SA Great†Literature Award in 2000 and the Peter McNamara Award for contributions to Australian speculative fiction in 2008.<br /><br />On the sci-fi front, he is best-known internationally for his original award-winning space opera series as well as several novels set in the Star Wars universe, many co-written with fellow-Adelaidean Shane Dix. These include the Astropolis, Evergence, Orphans and Geodesica series, and the computer game tie-in The Force Unleashed–the first such adaptation ever to debut at #1 on the New York Times bestseller list. A series for young readers, The Fixers, pitted an increasingly lost protagonist against zombies, cyborgs, and vampires across numerous universes. His most recent releases in the Star Wars universe are The Old Republic: Fatal Alliance and The Force Unleashed II.",
"autographs":"Complimentary at guest's discretion.",
"photographs":"",
"genre":"comic",
"links": [
{"linkname":"website", "url":"http://www.seanwilliams.com" }
]
},
{
"guestid":"17148603639603876",
"guestname":"Richard Dean Anderson",
"time":"10am",
"largeimg":"http://ozcomiccon.com/images/banner/richarddeananderson.jpg",
"smallimg":"http://ozcomiccon.com/images/banner/richarddeanandersonresized.jpg",
"biotext": "Richard Dean Anderson is probably best known as MacGyver, the clever and inventive nonviolent hero who solved problems in his own unique way for seven successful seasons on ABC. In his roles before and since, this gifted actor has continued to demonstrate his remarkable talent and versatility.<br /><br />Richard was born on January 23, 1950 in Minneapolis, Minnesota. His father, Stuart Anderson, taught English, drama, and humanities at a local high school, and is an accomplished jazz bassist. His mother, Jocelyn, is an artist, talented in both painting and sculpture. Richard is the eldest of four sons. He and his brothers, Jeffrey Scott, Thomas John, and James Stuart, grew up in the Minneapolis suburb of Roseville, where Richard developed early interests in sports, the arts, music, and acting.<br /><br />Like many boys growing up in Minnesota, Richard dreamed of becoming a professional hockey player. However, at the age of 16, he broke both arms, in separate accidents three weeks apart, while playing in high school hockey games. He put aside his dreams of playing professionally, though he still harbors a deep love for the sport. Richard talks of his restlessness growing up, his early desire to explore, and his adventures hitchhiking and hopping freight trains. At the age of 17, he took a 5641 mile bicycle trip from his home in Minnesota through Canada and Alaska, an experience which was sparked by his sense of adventure and discovery, but which also gave him a more centered sense of direction.",
"autographs":"Autograph from Richard $50.",
"photographs":"Photograph with Richard $80. SG1 double shot with Richard and Teryl Rothery $150. SG1 triple shot with Richard, Teryl Rothery and Corin Nemec $200.",
"genre":"acting",
"links": [
{"linkname":"Website", "url":"http://www.rdanderson.com/" },
{"linkname":"Twitter", "url":"https://twitter.com/andersonrdean" }
]
}
]
}
]
}
]
I have object class named Name, and I want to put all the data of the name(perth) jsonobject as a single object of the Name class. But it is not adding data in the arraylist correctly, more clearly the guestid, guestname etc tag values are being saved but overwrites the previous one. Here is my parsing code:
public ArrayList<Guest> parseInitiator() throws ClientProtocolException,
IOException, JSONException {
InputStream is = new FileInputStream(new File(Url));
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
String mResponse = new String(buffer);
JSONObject first = new JSONObject(mResponse);
JSONArray firstarray = first.getJSONArray("location");
ArrayList<Guest> parsedData = new ArrayList<Guest>();
for (int i = 0; i < firstarray.length(); i++) {
JSONObject jonj = firstarray.getJSONObject(i);
name = jonj.getString("name");
JSONArray confarray = jonj.getJSONArray("conferencelocation");
locationname = new String[confarray.length()];
for (int j = 0; j < confarray.length(); j++) {
JSONObject conobbj = confarray.getJSONObject(j);
locationname[j] = conobbj.getString("locationname");
JSONArray guestarray = conobbj.getJSONArray("guests");
guestid= new String[guestarray.length()];
guestname= new String[guestarray.length()];
time= new String[guestarray.length()];
largeimg= new String[guestarray.length()];
smallimg= new String[guestarray.length()];
biotext= new String[guestarray.length()];
autographs= new String[guestarray.length()];
photographs= new String[guestarray.length()];
genre= new String[guestarray.length()];
for (int k = 0; k < guestarray.length(); k++) {
JSONObject guestobbj = guestarray.getJSONObject(k);
guestid[k] = guestobbj.getString("guestid");
guestname[k] = guestobbj.getString("guestname");
time[k] = guestobbj.getString("time");
largeimg[k] = guestobbj.getString("largeimg");
smallimg[k] = guestobbj.getString("smallimg");
biotext[k] = guestobbj.getString("biotext");
autographs[k] = guestobbj.getString("autographs");
photographs[k] = guestobbj.getString("photographs");
genre[k] = guestobbj.getString("genre");
JSONArray linkar = guestobbj.getJSONArray("links");
arlink= new String[linkar.length()];
arurl= new String[linkar.length()];
for (int l = 0; l < linkar.length(); l++) {
JSONObject linkobj = linkar.getJSONObject(l);
arlink[l] = linkobj.getString("linkname");
arurl[l] = linkobj.getString("url");
}
}
}
parsedData.add(new Guest(name,locationname, guestid, guestname, time, largeimg, smallimg, biotext,
autographs, photographs, genre,arlink, arurl));
}
return parsedData;
}
Can anyone make me clear about the mistake I have made?
So here is my solution:
JSONObject first = new JSONObject(mResponse);
JSONArray locArr = first.getJSONArray("location"); // contains one object
JSONObject locArrObj = locArr.getJSONObject(0); // cotains one "out" array
JSONArray conferenceLocArr = locArrObj.getJSONArray("conferencelocation");
// this array has two objects and each object has array
JSONObject o = null;
JSONArray arr = null;
for (int i = 0; i < conferenceLocArr.length(); i++) {
o = conferenceLocArr.getJSONObject(i); // it has one array
arr = o.getJSONArray("guests");
// do your work with Stage 1 and guests
// and for second object for Stage 2 and guests.
}
Related
using Json file in Java
I am trying to import a json file and use the data inside it and export the file as json file Use the file movies.json to initialize the Movie Library, and export a modified Json file to save the library upon completion of the program. private Vector<MovieDescription> libraryList = new Vector<MovieDescription>(); public static void main(String args[]) { try { MovieLibrary movies = new MovieLibrary(); // Input the group from movies.json System.out.println("Importing group from movies.json"); MovieLibrary movies1 = new MovieLibrary("movies.json"); movies1.add(new MovieDescription("Suicide Squad", "PG-13", "05 August 2016", " 2h 3min", "Fearing that the world is vulnerable to otherworldly threats, the Government enlists the disposable Task Force X on a high-risk mission in exchange for absolution: Meanwhile, the Joker operates his own agenda.", "Suicide Squad.mp4", "Action, Adventure, Crime", " Will Smith, Jared Leto, Margot Robbie ")); movies.add(new MovieDescription("Sausage Party", "R", "12 August 2016", "1h 29min", "The products at Shopwell's Grocery Store are made to believe a code that helps them live happy lives until it's time for them to leave the comfort of the supermarket and head for the great beyond. However, after a botched trip to the great beyond leaves one sausage named Frank and his companion Bun stranded, Frank goes to great lengths (pun intended) to return to his package and make another trip to the great beyond. But as Frank's journey takes him from one end of the supermarket to the other, Frank's quest to discover the truth about his existence as a sausage turns incredibly dark. Can he expose the truth to the rest of the supermarket and get his fellow products to rebel against their human masters?", "Sausage Party.mp4", "Animation, Adventure, Comedy", " Seth Rogen, Kristen Wiig, Jonah Hill")); movies.add(new MovieDescription("Deadpool", "R", "12 February 2016", "1h 48min", "A former Special Forces operative turned mercenary is subjected to a rogue experiment that leaves him with accelerated healing powers, adopting the alter ego Deadpool. ", "Deadpool.mp4", "Action, Adventure, Comedy", " Ryan Reynolds, Morena Baccarin, T.J. Miller")); movies1.printLibrary(); PrintWriter out = new PrintWriter("moviesJava.json"); out.println(movies1.toJSONString()); out.close(); System.out.println("Done exporting group in json to movies.json"); // now use java's built in serialization to serialize and // deserialize File outFile = new File("movies.ser"); ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(outFile)); os.writeObject(movies); os.flush(); System.out.println("Used Java serialization of the group to movies.ser"); os.close(); File inFile = new File("movies.ser"); ObjectInputStream in = new ObjectInputStream(new FileInputStream(inFile)); MovieLibrary movieAgain = (MovieLibrary) in.readObject(); System.out.println("Done importing the group from movies.ser as:"); movieAgain.printLibrary(); in.close(); } catch (Exception e) { System.out.println("exception: " + e.getMessage()); e.printStackTrace(); } } and this is the toJsonString method public String toJSONString() { String ret; JSONObject obj = new JSONObject(); for (Enumeration<MovieDescription> e = libraryList.elements(); e.hasMoreElements();) { MovieDescription movi = (MovieDescription) e.nextElement(); try { obj.put(movi.getTitle(), movi.toJson()); /* * obj.put(movi.getActors(),movi.toJson()); * obj.put(movi.getFilename(),movi.toJson()); * obj.put(movi.getGenre(),movi.toJson()); * obj.put(movi.getPlot(),movi.toJson()); * obj.put(movi.getRated(),movi.toJson()); * obj.put(movi.getReleased(),movi.toJson()); * obj.put(movi.getRuntime(),movi.toJson()); */ } catch (JSONException e1) { e1.printStackTrace(); } } ret = obj.toString(); return ret; } I'm getting the following exception: org.json.JSONException: Null key. at org.json.JSONObject.put(JSONObject.java:1097) at MovieLibrary.toJSONString(MovieLibrary.java:124) at MovieLibrary.main(MovieLibrary.java:69)
A cleaner way of doing this is by using Jackson. Create class MovieLibrary with getter and setter methods for each variable inside it. ObjectMapper mapper = new ObjectMapper(); MovieLibrary movies = new MovieLibrary(); //Object to JSON in file mapper.writeValue(new File("c:\\file.json"), movies); The above code will map the data in the file to object of MovieLibraary(movies). You can modify the value in movies object by using setter methods. http://www.mkyong.com/java/jackson-2-convert-java-object-to-from-json/
Parsing a Tab Separated File
I'm attempting to TSV from IMDB: $hutter Battle of the Sexes (2017) (as $hutter Boy) [Bobby Riggs Fan] <10> NVTION: The Star Nation Rapumentary (2016) (as $hutter Boy) [Himself] <1> Secret in Their Eyes (2015) (uncredited) [2002 Dodger Fan] Steve Jobs (2015) (uncredited) [1988 Opera House Patron] Straight Outta Compton (2015) (uncredited) [Club Patron/Dopeman] $lim, Bee Moe Fatherhood 101 (2013) (as Brandon Moore) [Himself - President, Passages] For Thy Love 2 (2009) [Thug 1] Night of the Jackals (2009) (V) [Trooth] "Idle Talk" (2013) (as Brandon Moore) [Himself] "Idle Times" (2012) {(#1.1)} (as Brandon Moore) [Detective Ryan Turner] As you can some lines start with a tab and some do not. I want a map with the actor's name as a key and a list of movies as the value. Between the actor's name is one or more tabs to until the movie listing. My code: while ((line = reader.readLine()) != null) { Matcher matcher = headerPattern.matcher(line); boolean headerMatchFound = matcher.matches(); if (headerMatchFound) { Logger.getLogger(ActorListParser.class.getName()).log(Level.INFO, "Header for actor list found"); String newline; reader.readLine(); while ((newline = reader.readLine()) != null) { String[] fullLine = null; String actor; String title; Pattern startsWithTab = Pattern.compile("^\t.*"); Matcher tab = startsWithTab.matcher(newline); boolean tabStartMatcher = tab.matches(); if (!tabStartMatcher) { fullLine = newline.split("\t.*"); System.out.println("Actor: " + fullLine[0] + "Movie: " + fullLine[1]); }//this line will have code to match lines that start with tabs. } } } The way I've done this only works for a few lines before I get and arrayoutofbounds exception. How can I parse the lines and split them into 2 strings at max if they have one or more tabs?
There are subtleties in parsing tab/comma-delimited data files having to do with quoting and escaping. To save yourself a lot of work, frustration and headaches you really should consider using one of the existing CSV parsing libaries such as OpenCSV or Apache Commons CSV. Posted as an answer instead of a comment because the OP has not stated a reason for reinventing the wheel and there are some tasks that really have been "solved" once and for all.
script to search address on google maps
I have names of 1100 hospitals from NY region. I need to find the address of these hospitals from google. I am looking for some script which I can use to supply all these hospital name and it could return me with an address. The script could return a simple google search result. Input format: Hospital Name Center for Ambulatory Surgery Genetic Diagnostic Labs Inc Desired output format: Hospital Name Hospital Address Center for Ambulatory Surgery 3112 Sheridan Dr, Amherst, NY 14226 Genetic Diagnostic Labs Inc 490 Delaware Ave, Buffalo, NY 14202
A solution with google Places API, but the results may be not very accurate: http://codepen.io/anon/pen/JogeyV?editors=101 var NY_latlng = new google.maps.LatLng(40.828624, -73.898605); map = new google.maps.Map(document.getElementById('map-canvas'), { center: NY_latlng, zoom: 15 }); var hospitals = []; var hospitals_names = ["Center for Ambulatory Surgery","Genetic Diagnostic Labs Inc"];//insert your full list here var service = new google.maps.places.PlacesService(map); hospitals_names.forEach( function(name ){ service.textSearch( { query: name, location: NY_latlng, radius: 50000, //in meter },function(results,status){ if (status == google.maps.places.PlacesServiceStatus.OK){ var hospital= { name: name, addresses: []}; $('#address-list').append("<h2>"+name+"</h2><ul></ul>"); for (var i = 0; i < results.length; i++) { hospital.addresses.push( results[i].formatted_address ); $('#address-list > ul').append("<li>"+results[i].formatted_address); } hospitals.push( hospital ); } });
You can do this in R with the ggmap package, though perhaps not reliably enough to produce the results you want. For instance this attempt to geocode fails: geocode("Genetic Diagnostic Labs Inc") Warning message: geocode failed with status ZERO_RESULTS, location = "Genetic Diagnostic Labs Inc" So to illustrate a solution, I appended " NY" to the Google searches: library(ggmap) hospital_names <- c("Center for Ambulatory Surgery", "Genetic Diagnostic Labs Inc") address_vec <- lapply(hospital_names, function(x) revgeocode(as.numeric(geocode(paste(x,", NY"))))) result <- data.frame(name = hospital_names, address = unlist(address_vec)) Result: result name address 1 Center for Ambulatory Surgery 426 Union Road, West Seneca, NY 14224, USA 2 Genetic Diagnostic Labs Inc City Hall Park Path, New York, NY 10007, USA But these are not the addresses you specified - you may need to refine your inputs.
storing transactions in an OrderedList
I'm a Java noob so please bear with me. I'm having an issue with a java project I have to complete. We have to sort a list of 10,000 customer transactions, pick the top three customers that spent the most, then give five random customers gift cards, five of them starting at $20 and ending at $100, increasing in $20 increments. So far I have the following: public static void main(String[] args) throws IOException { BufferedReader inputStream = new BufferedReader (new FileReader("Transactions.txt")); BufferedWriter outputStream = new BufferedWriter (new FileWriter("output.txt")); Scanner trans = null; try { trans = new Scanner(new BufferedReader(new FileReader("Transactions.txt"))); trans.useDelimiter("s*"); while (trans.hasNext()) { System.out.println(trans.next()); } } finally { if (trans !=null) { trans.close(); I'm confused as to how I would put this information into an OrderedList so it'll sort them in ascending order according to the amount they spent. EDIT: Here are some lines from the transaction.txt file: Order # Date First name Middle Initial Last name Address City State Zip Email Transaction Amount 1 8/26/2012 Kristina H Chung 947 Martin Ave. Muncie CA 46489 khchung#business.com $593 2 11/16/2012 Paige H Chen 15 MainWay Rd. Dallas HI 47281 phchen#business.com $516 3 11/10/2012 Sherri E Melton 808 Washington Way Brazil CA 47880 semelton#business.com $80 4 9/20/2012 Gretchen I Hill 56 Washington Dr. Atlanta FL 47215 gihill#business.com $989 5 3/11/2012 Karen U Puckett 652 Maplewood Ct. Brazil FL 46627 kupuckett#business.com $826 My apologies, but I have no idea how to make this look neat.
Java reading information from a website using Jsoup
I've gone through multiple posts about parsing and such. Most of the responses that I saw were recommending the person to use a Library or something else. My problem right now is creating an algorithm that will fetch the exact information I want. My purpose for this is to fetch 2 statuses from the Weather website for school closings. I started using Jsoup as someone recommended but I need help with it. Webpage: Click here Image: Click here Example of webpage source: click here I could probably figure out how to get a certain line of text within the webpage since I already know the name of the school im looking for, but 2 lines down is the status which is what I need. would be easy if each school had a certain status but they are all either Closed or Two-hour Delay so I can't just make a search for that. I want some ideas or answers on how i can apporach this. I am going to do this 2 times because I am wanting to look up 2 schools. I already have the names which I can use to look them up I just need the status. Here is an example of what I want to do. (sudo code) Document doc = connect(to url); Element schoolName1 = doc.lookForText(htmlLineHere/schoolname); String status1 = schoolName.getNext().text();//suppose this gets the line right after which should be my status and then cleans off the Html. This is what I have right now public static SchoolClosing lookupDebug() throws IOException { final ArrayList<String> Status = new ArrayList<String>(); try { //connects to my wanted website Document doc = Jsoup.connect("http://www.10tv.com/content/sections/weather/closings.html").get(); //selects/fetches the line of code I want Element schoolName = doc.html("<td valign="+"top"+">Athens City Schools</td>"); //an array of Strings where I am going to add the text I need when I get it final ArrayList<String> temp = new ArrayList<String>(); //checking if its fetching the text System.out.println(schoolName.text()); //add the text to the array temp.add(schoolName.text()); for (int i = 0; i <= 1; i++) { final String[] tempStatus = temp.get(i).split(" "); Status.add(tempStatus[0]); } } catch (final IOException e) { throw new IOException("There was a problem loading School Closing Status"); } return new SchoolClosing(Status); }
Document doc = Jsoup.connect( "http://www.10tv.com/content/sections/weather/closings.html") .get(); for (Element tr : doc.select("#closings tr")) { Element tds = tr.select("td").first(); if (tds != null) { String county = tr.select("td:eq(0)").text(); String schoolName = tr.select("td:eq(1)").text(); String status = tr.select("td:eq(2)").text(); System.out.println(String.format( "county: %s, schoolName: %s, status: %s", county, schoolName, status)); } } output: county: Athens, schoolName: Beacon School, status: Two-hour Delay county: Franklin, schoolName: City of Grandview Heights, status: Snow Emergency through 8pm Thursday county: Franklin, schoolName: Electrical Trades Center, status: All Evening Activities Cancelled county: Franklin, schoolName: Hilock Fellowship Church, status: PM Services Cancelled county: Franklin, schoolName: International Christian Center, status: All Evening Activities Cancelled county: Franklin, schoolName: Maranatha Baptist Church, status: PM Services Cancelled county: Franklin, schoolName: Masters Commission New Covenant Church, status: Bible Study Cancelled county: Franklin, schoolName: New Life Christian Fellowship, status: All Activities Cancelled county: Franklin, schoolName: The Epilepsy Foundation of Central Ohio, status: All Evening Activities Cancelled county: Franklin, schoolName: Washington Ave United Methodist Church, status: All Evening Activities Cancelled or in a loop: for (Element tr : doc.select("#closings tr")) { System.out.println("----------------------"); for (Element td : tr.select("td")) { System.out.println(td.text()); } } that gives: ---------------------- Athens Beacon School Two-hour Delay ---------------------- Franklin City of Grandview Heights Snow Emergency through 8pm Thursday ---------------------- Franklin Electrical Trades Center All Evening Activities Cancelled ...