I managed to print this website in JSON in Eclipse
https://www.quandl.com/api/v3/datasets/SSE/HYQ.json?start_date=2017-01-01&end_date=2017-01-31
As you can see, we have an array in which are stock values of a certain company. The array has a length of 22. For example:
["2017-01-27",89.13,87.611,88.18,87.699,750] //Array index 2
["2017-01-26",89.22,87.699,87.699,88.315,190]//Array index 3
["2017-01-31",86.77,84.312,84.32,84.81,1205]//Array index 0
My task is to check which one has the greater values. Like, checking if 89.13 is greater than 89.22? No, therefore checking if 89.22 > than 86.77, no and so on. And then printing out, at which date was the greatest value. The problem is to check that in Java. I don't know how to compare these 3 (not to mention 22)
EDIT: The logic is clear for me, my problem is to solve that in Java. An Example with these 3 given above would be nice.
Here is my code:
package query;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.*;
import java.io.*;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Stockquery {
public static void main(String[] args) {
String jsonString = callURL(
"https://www.quandl.com/api/v3/datasets/SSE/HYQ.json?start_date=2017-01-01&end_date=2017-01-31");
try {
JSONObject jsonobjects = new JSONObject(jsonString);
JSONObject dataset = jsonobjects.getJSONObject("dataset");
JSONArray array = dataset.getJSONArray("data");
System.out.println(array.get(2));
System.out.println(array.get(3));
array.getString(0);
System.out.println(array.getString(0));
} catch (JSONException e) {
e.printStackTrace();
}
}
public static String callURL(String myURL) {
// System.out.println("Requested URL:" + myURL);
StringBuilder sb = new StringBuilder();
URLConnection urlConn = null;
InputStreamReader in = null;
try {
URL url = new URL(myURL);
urlConn = url.openConnection();
if (urlConn != null)
urlConn.setReadTimeout(60 * 1000);
if (urlConn != null && urlConn.getInputStream() != null) {
in = new InputStreamReader(urlConn.getInputStream(), Charset.defaultCharset());
BufferedReader bufferedReader = new BufferedReader(in);
if (bufferedReader != null) {
int cp;
while ((cp = bufferedReader.read()) != -1) {
sb.append((char) cp);
}
bufferedReader.close();
}
}
in.close();
} catch (Exception e) {
throw new RuntimeException("Exception while calling URL:" + myURL, e);
}
return sb.toString();
}
}
JSON array's element is a JSON element. Since JSON element can be a JSON array, a JSON array can contains JSON arrays as its elements.
Something like that will do it:
JSONArray array = dataset.getJSONArray("data");
// Save the first array's values
String biggestDate = array.get(0).get(0); // index 0 is the date
double biggest = array.get(0).get(1); // index 1 is the stock price
// Iterate over all arrays and update biggest
for (int i = 0; i < 22; i++) {
JSONArray arrayI = array.get(i);
if (arrayI.get(1) > biggest) {
biggest = arrayI.get(1); // updating biggest
biggestDate = arrayI.get(0); // updating biggest's date
}
}
return biggestDate;
Note: Not tested!
Of course, don't use 22 and other hard-coded constants
Used double for simplicity, use BigDecimal
Implement the method below.
private static String getDateWithMaxValue(JSONArray array) throws JSONException {
JSONArray stockData;
String dateWithMaxValue = "";
double maxValue = Double.MIN_VALUE;
for (int i = 0; i < array.length(); i++) {
stockData = array.getJSONArray(i);
if (stockData.get(1) instanceof Double) {
if (((Double) stockData.get(1)).doubleValue() > maxValue) {
maxValue = ((Double) stockData.get(1)).doubleValue();
if (stockData.get(0) instanceof String) {
dateWithMaxValue = (String) stockData.get(0);
}
}
}
}
return dateWithMaxValue;
}
And just add the call
System.out.println(getDateWithMaxValue(array));
in your main to print the date with the maximum value at index 1, where array is the JSONArray that you already declared.
(Code tested and returned date 2017-01-26, which is correct)
Did array.get(0).get(0) work for you?
For me not. I had to parse:
Optional<String> maxRow = array.toList().stream().map(Object::toString).max(new Comparator<String>() { #Override public int compare(String o1, String o2) {
return Double.valueOf(o1.split(",")[1]).compareTo(Double.valueOf(o2.split(",")[1])); }
});
System.out.println("Max row: " + maxRow.get());
which resulted with the "max" line:
Max row: [2017-01-26, 89.22, 87.699, 87.699, 88.315, 190.0]
Related
I'm new to Java and i was using python and coding is different for me. I'm trying to make a string count with java , I have a problem when I execute it doesn't update the values of my json file it creates another textual in the subdirectory here is my code:
package sender;
import java.util.Iterator;
import java.util.Scanner; // import the Scanner class
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.*;
public class contar {
public static void main(String[] args) throws ParseException, IOException {
Scanner myObj = new Scanner(System.in);
String userName;
char[] cadena;
char caracter;
// Enter username and press Enter
System.out.println("Enter username");
userName = myObj.nextLine();
cadena = userName.toCharArray();
boolean[] yaEstaElCaracter = new boolean[Character.MAX_VALUE];
int[] cuantasVeces = new int[Character.MAX_VALUE];
for(int i =0;i<cadena.length;i++){
caracter = cadena[i];
System.out.println(caracter);
if(cadena[i]==caracter){
cuantasVeces[caracter]++;
}
yaEstaElCaracter[caracter] = true;
}//Fin Para
//Crea el json
Object a;
Object b;
JSONObject jsd = new JSONObject();
jsd.put("listado","2");
JSONArray list = new JSONArray();
JSONObject obj = new JSONObject();
for(int i = 0; i < yaEstaElCaracter.length; i++){
if(yaEstaElCaracter[i]) {
a= (char) i;
b = cuantasVeces[i];
//JSONObject jsd = new JSONObject();
/*jsd.put("listado","2");
JSONArray list = new JSONArray();
JSONObject obj = new JSONObject();*/
obj.put((char) i,cuantasVeces[i] );
System.out.println((char) i +" "+cuantasVeces[i]+" veces.");
}
}
list.add(obj);
jsd.put("frecuencias", list);
File l = new File("C:\\Users\\andre\\Documents\\9SEMENESTRE\\FATIGA\\tarea");
String[] bus = l.list();
if (bus == null || bus.length == 0) {
System.out.println("No hay elementos dentro de la carpeta actual");
try (FileWriter file = new FileWriter("C:\\Users\\andre\\Documents\\9SEMENESTRE\\FATIGA\\tarea\\Reporte.json")){
file.write(jsd.toString());
file.flush();
file.close();
}catch(Exception e) {}
}else {
JSONParser jsonParser = new JSONParser();
try (FileReader reader = new FileReader("C:\\Users\\andre\\Documents\\9SEMENESTRE\\FATIGA\\tarea\\Reporte.json"))
{
Object abc = jsonParser.parse(reader);
JSONObject letras = (JSONObject) abc;
JSONArray lang = (JSONArray) letras.get("frecuencias");
for (int k = 0; k < lang.size(); k++) {
System.out.println("The " + k + " element of the array: " + lang.get(k));
}
Iterator k = lang.iterator();
JSONObject jsonObject = new JSONObject(contents.trim());
Iterator<String> keys = jsonObject.keys();
while(keys.hasNext()) {
String key = keys.next();
if (jsonObject.get(key) instanceof JSONObject) {
JSONArray
}
}
while (k.hasNext()) {
JSONObject innerObj = (JSONObject) k.next();
for (int i = 0; i < innerObj.size(); i++) {
System.out.println(i);
}
//System.out.println(innerObj.get(cadena.toString()));
}
//Iterate over employee array
//employeeList.forEach( emp -> parseEmployeeObject( (JSONObject) emp ) );
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
}
This is my output:
{"listado":"2","frecuencias":[{" ":6,"a":4,"c":2,"d":2,"e":3,"g":1,"i":4,"m":3,"o":5,"p":1,"q":1,"r":2,"s":1,"t":1,"u":1,"y":1}]}{"a":6,c":2,"d":2,"e":3,} <---- I don't need this just update it
First you need to fix this catch(Exception e) {}. If you hide or don't do anything with an exception then you will have no idea what has broken and why. Also, you only ever write to the file if bus == null or if bus.length == 0, is that correct? And then you only ever write your file to "C:\\Users\\andre\\Documents\\9SEMENESTRE\\FATIGA\\tarea\\Reporte.json" is that path correct?
Edit your code to include some debugging and to show the error message:
if (bus == null || bus.length == 0) {
System.out.println("No hay elementos dentro de la carpeta actual");
try (FileWriter file = new FileWriter("C:\\Users\\andre\\Documents\\9SEMENESTRE\\FATIGA\\tarea\\Reporte.json")){
//Print a message to check if your code ever for here
System.out.println("Attempting to write the file");
file.write(jsd.toString());
file.flush();
//Print a success message
System.out.println("The file was successfully written to");
}
catch(Exception e) {
//Print the error to the console
e.printStackTrace();
}
}
Now you will be able to see if your code even got as far as writing to the file, and why it failed.
If you are still stuck then you need to update your question to include more information, including debugging details.
First, what is contents in JSONObject jsonObject = new JSONObject(contents.trim());? I'm pretty sure you're referencing a variable above that you changed the name of at some point, because I don't see it anywhere else in this code.
Iterator k = lang.iterator();
JSONObject jsonObject = new JSONObject(contents.trim());
Iterator<String> keys = jsonObject.keys();
while(keys.hasNext()) {
String key = keys.next();
if (jsonObject.get(key) instanceof JSONObject) {
JSONArray
}
}
while (k.hasNext()) {
JSONObject innerObj = (JSONObject) k.next();
for (int i = 0; i < innerObj.size(); i++) {
System.out.println(i);
}
//System.out.println(innerObj.get(cadena.toString()));
}
Somewhere in here you're missing a call to jsd.
I haven't run the script, but just reading it over, what I see is that you check to see if the file you are looking for exists, and if it doesn't you create the file using the data you have parsed into the object jsd. But if it does exists, you never do that. You seem to correctly open the file, read it into the buffer, and then ... you read that file back into the same file? Actually, you don't seem to do anything with it.
So I think that's where your issue is.
Two things to help:
Like sorifiend alludes to, use your catchs better. Put some sort of println or message for each one that lets you know where the error occured, what type it is, and then, yeah print the stack trace.
I suggest you go through and write comments about what need to get done, and about each step that's being completed. Lean towards the side of being overly explicit. Even write a comment for each line. This way, when you are looking through your code, you'll notice when you aren't doing something important (like writing to the file).
I am trying to extract a value from a while loop. In the output, I am able to capture the value in the Else statement but not able to return it when it is in the console log from the main statement. I want to be able to return "103" when I call the getValueFromkey() function.
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.XML;
public class Tesst {
static String line = "", str = "";
public static void main(String[] args) throws Exception {
String filepath = "C:/Users/Navi/Downloads/sample.xml";
BufferedReader br = new BufferedReader(new FileReader(filepath));
while ((line = br.readLine()) != null) {
str += line;
}
br.close();
JSONObject jsondata = XML.toJSONObject(str);
System.out.println("From main: " + getValueFromKey(jsondata, "routing_bic"));
}
private static Integer getValueFromKey(JSONObject json, String key) {
boolean exists = json.has(key);
Iterator<?> keys;
String nextKeys;
Integer foundKey = 0;
if(!exists) {
keys = json.keys();
while (keys.hasNext()) {
// Store next Key in nextKeys
nextKeys = (String)keys.next();
try {
// Check if the given Key is a JSON Object
if(json.get(nextKeys) instanceof JSONObject) {
// If Key does not exist
if(!exists) {
// Recursive function call
getValueFromKey(json.getJSONObject(nextKeys), key);
}
} else if (json.get(nextKeys) instanceof JSONArray) {
JSONArray jsonArray = json.getJSONArray(nextKeys);
for(int i = 0; i < jsonArray.length(); i++) {
String jsonArrayString = jsonArray.get(i).toString();
JSONObject innerJsonObject = new JSONObject(jsonArrayString);
// Recursive function call
if(!exists) {
getValueFromKey(innerJsonObject.getJSONObject(nextKeys), key);
}
}
}
} catch (Exception e) {
System.out.println(e);
}
}
} else {
// If key exists, print value
foundKey += parseObject(json, key);
System.out.println("From loop: " + foundKey);
return foundKey;
}
// System.out.println("Found Key = " + foundKey);
return 1; // Return 1 when key not found
}
private static Integer parseObject(JSONObject json, String key) {
System.out.println("From parseObject = " + json.get(key));
return (Integer) json.get(key);
}
}
Sample XML
<Test>
<BIBRq>
<UserId>123</UserId>
<CIFNo>123</CIFNo>
<CompanyId>asd</CompanyId>
<LegalId>123</LegalId>
<LegalIdType>ABC</LegalIdType>
<LegalIdCountry>ABC</LegalIdCountry>
</BIBRq>
<SubSvcRq>
<SubSvc>
<SubSvcRqHeader>
<SvcCode>ABCD</SvcCode>
<SubSvcSeq>1</SubSvcSeq>
<TxnRef>12345</TxnRef>
<ClientUserID/>
</SubSvcRqHeader>
<SubSvcRqDetail>
<ft_tnx_record>
<additional_field>
<account_details>
<routing_bic>103</routing_bic>
</account_details>
</additional_field>
</ft_tnx_record>
</SubSvcRqDetail>
</SubSvc>
</SubSvcRq>
</Test>
Output:
From parseObject = 103
From loop: 103
From main: 1
There are two errors in your code.
I notice that you recursively call the function getValueFromKey. That will never work if you don't assign the variable foundKey with the return value of the recursive invocation.
So, just change each recursive calls in this:
foundKey = getValueFromKey(..., key);
In addition, the last statement return 1 is wrong, because it will override any possible value returned by the subsequent recursive invocation. So, in replacement, you have to return always the foundKey variable.
I slightly changed your code and tested it with your sample file and it works fine. Differently than yours, I also wrapped the BufferedReader with try-with-resouce block, which I always prefer to simple try-catch, because it garantees that it closes the stream for you, even in case of exceptions.
Here is the code:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.XML;
public class Test {
static String line = "", str = "";
public static void main(String[] args) throws Exception {
String filepath = "C:\\Users\\marco\\Downloads\\sample.xml";
try ( BufferedReader br = new BufferedReader(new FileReader(filepath)); ) {
while ((line = br.readLine()) != null) {
str += line;
}
}
JSONObject jsondata = XML.toJSONObject(str);
System.out.println("From main: " + getValueFromKey(jsondata, "routing_bic"));
}
private static Integer getValueFromKey(JSONObject json, String key) {
boolean exists = json.has(key);
Iterator<?> keys;
String nextKeys;
Integer foundKey = 0;
if(!exists) {
keys = json.keys();
while (keys.hasNext()) {
// Store next Key in nextKeys
nextKeys = (String)keys.next();
try {
// Check if the given Key is a JSON Object
if(json.get(nextKeys) instanceof JSONObject) {
// If Key does not exist
if(!exists) {
// Recursive function call
foundKey = getValueFromKey(json.getJSONObject(nextKeys), key);
}
} else if (json.get(nextKeys) instanceof JSONArray) {
JSONArray jsonArray = json.getJSONArray(nextKeys);
for(int i = 0; i < jsonArray.length(); i++) {
String jsonArrayString = jsonArray.get(i).toString();
JSONObject innerJsonObject = new JSONObject(jsonArrayString);
// Recursive function call
if(!exists) {
foundKey = getValueFromKey(innerJsonObject.getJSONObject(nextKeys), key);
}
}
}
} catch (Exception e) {
System.out.println(e);
}
}
} else {
// If key exists, print value
foundKey += parseObject(json, key);
System.out.println("From loop: " + foundKey);
}
// System.out.println("Found Key = " + foundKey);
return foundKey; // Return 1 when key not found
}
private static Integer parseObject(JSONObject json, String key) {
System.out.println("From parseObject = " + json.get(key));
return (Integer) json.get(key);
}
}
And here is the output:
From parseObject = 103
From loop: 103
From main: 103
So I am trying to create 5 different entries into a web form using Java Selenium.
With the code below it is reading from the CSV and inputting the first entry but then just adds the same data 5 times rather than the 5 different entries in the csv and I can't figure out where I have gone wrong?
#Then("^I can make multiple bookings$")
public void i_can_make_multiple_bookings() throws Throwable {
String csvFile = "hotelsDatas.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// Use comma as separator
String[] hotels = line.split(cvsSplitBy);
// Reading a line column by column
for (int i = 0; i < hotels.length; i++) {
System.out.print(hotels[i].replaceAll("\"", ""));
driver.findElement(By.id("firstName")).sendKeys(hotels[0].replaceAll("\"", ""));
driver.findElement(By.id("lastName")).sendKeys(hotels[1].replaceAll("\"", ""));
driver.findElement(By.id("totalPrice")).sendKeys(hotels[2].replaceAll("\"", ""));
driver.findElement(By.id("depositPaid")).sendKeys(hotels[3].replaceAll("\"", ""));
driver.findElement(By.id("checkIn")).sendKeys(hotels[4].replaceAll("\"", ""));
driver.findElement(By.id("checkOut")).sendKeys(hotels[5].replaceAll("\"", ""));
driver.findElement(By.id("createBooking")).click();
}
System.out.println(); // next line
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Why don't you just read in the CSV file first as a List<Map> and work from there?
After that, you can iterate over the List and for each Map, do things with each Key-Value pair.
import java.io.*;
import java.lang.reflect.Type;
import java.util.*;
import java.util.stream.Collectors;
import com.opencsv.CSVReader;
public class Reader {
public static List<Map<String, Object>> readCsv(String filename) throws IOException {
return readCsv(filename, null, null);
}
public static List<Map<String, Object>> readCsv(String filename, String[] headers) throws IOException {
return readCsv(filename, headers, null);
}
public static List<Map<String, Object>> readCsv(String filename, Type[] types) throws IOException {
return readCsv(filename, null, types);
}
public static List<Map<String, Object>> readCsv(String filename, String[] headers, Type[] types) throws IOException {
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
InputStream is = Reader.class.getClassLoader().getResourceAsStream(filename);
InputStreamReader reader = new InputStreamReader(is);
CSVReader csv = new CSVReader(reader);
if (headers == null) {
headers = csv.readNext();
}
String[] row;
while ((row = csv.readNext()) != null) {
Map<String, Object> entry = new HashMap<String, Object>();
for (int i = 0; i < row.length; i++) {
String value = row[i];
if (types != null) {
if (types[i] == Double.class) {
entry.put(headers[i], Double.parseDouble(value));
} else if (types[i] == Date.class) {
entry.put(headers[i], new Date(Long.parseLong(value)));
} else if (types[i] == Boolean.class) {
entry.put(headers[i], new Boolean(value.toLowerCase().equals("true") || value.toLowerCase().equals("yes")));
} else {
entry.put(headers[i], value);
}
}
}
result.add(entry);
}
csv.close();
reader.close();
is.close();
return result;
}
public static void main(String[] args) {
try {
Type[] types = { String.class, String.class, Double.class, Boolean.class, Date.class, Date.class };
List<Map<String, Object>> records = readCsv("data.csv", types);
System.out.println(records.stream().map(Object::toString).collect(Collectors.joining(System.lineSeparator())));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Input
firstName,lastName,totalPrice,depositPaid,checkIn,checkOut
Jane,Doe,200.00,yes,1512129600000,1512331200000
John,Smith,350.00,no,1512720000000,1512925200000
Output
{firstName=Jane, lastName=Doe, checkIn=Fri Dec 01 07:00:00 EST 2017, totalPrice=200.0, checkOut=Sun Dec 03 15:00:00 EST 2017, depositPaid=true}
{firstName=John, lastName=Smith, checkIn=Fri Dec 08 03:00:00 EST 2017, totalPrice=350.0, checkOut=Sun Dec 10 12:00:00 EST 2017, depositPaid=false}
Dependencies
Gradle
compile 'com.opencsv:opencsv:4.1'
or Maven
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>4.1</version>
<type>pom</type>
</dependency>
or Direct Download
>> opencsv-4.1 (jar)
Below code is causing you trouble:
String[] hotels = line.split(cvsSplitBy);
// Reading a line column by column
for (int i = 0; i < hotels.length; i++) {
System.out.print(hotels[i].replaceAll("\"", ""));
driver.findElement(By.id("firstName")).sendKeys(hotels[0].replaceAll("\"", ""));
driver.findElement(By.id("lastName")).sendKeys(hotels[1].replaceAll("\"", ""));
driver.findElement(By.id("totalPrice")).sendKeys(hotels[2].replaceAll("\"", ""));
driver.findElement(By.id("depositPaid")).sendKeys(hotels[3].replaceAll("\"", ""));
driver.findElement(By.id("checkIn")).sendKeys(hotels[4].replaceAll("\"", ""));
driver.findElement(By.id("checkOut")).sendKeys(hotels[5].replaceAll("\"", ""));
driver.findElement(By.id("createBooking")).click();
}
Lets suppose data in csv file looks like this:
"one","two","three","four","five","six","seven","eight","nine","ten"
You split data with , and create an instance of String[] with String[] hotels = line.split(cvsSplitBy);
This means your hotels[] array looks like this:
hotels[0] = "\"one\""; (I used String escape, because as I can see, you are replacing " in your code in for loop.
hotels[1] = "\"two\"";
hotels[2] = "\"three\"";
hotels[3] = "\"four\"";
hotels[4] = "\"five\"";
hotels[5] = "\"six\"";
hotels[6] = "\"seven\"";
hotels[7] = "\"eight\"";
hotels[8] = "\"nine\"";
hotels[9] = "\"ten\"";
Now take a look at for loop
for (int i = 0; i < hotels.length; i++)
Since the hotels.length gives you 10 elements, for loop wil be performed 10 times.
NOW TAKE A LOOK AT EACH ITERATION:
i=0
System.out.println will print one in the console.
driver will enter one in firstName
driver will enter two in lastName
driver will enter three in totalPrice
etc.
and it will click createBooking element.
AND IT WAS ONLY THE FIRST ITERATION.
When we go to iteration i=1 then System will print two. But since driver.findElement's code is in for loop, it will enter THE SAME DATA IN THE SAME FIELDS AGAIN. AND IT WILL KEEP DOING THAT OVER AND OVER, UNTIL ITERATION FINISHES.
You should get rid of for loop. You don't need it.
Using Eclipse, I’m converting data to JSON. I’ve downloaded the json.jar file and added it to my class path. I’ve imported these,
import org.json.JSONArray;
import org.json.JSONObject;
But when I try to use .add, .toJSONString and .contains I get errors like these,
The method add(String) is undefined for the type JSONArray
The method add(JSONObject) is undefined for the type JSONArray
The method toJSONString() is undefined for the type JSONObject
Why is this happening? Here is the full code below.
private JSONObject getJson(){
JSONObject obj = new JSONObject();
String forename = null;
String surname = null;
JSONArray nodes = new JSONArray();
JSONArray links = new JSONArray();
Map<Integer,Integer> sourceMap = new HashMap<Integer, Integer>();
Map<Integer, Integer> targetMap = new HashMap<Integer, Integer>();
int linkSourceActivity = -1;
int linkTargetActivity = -1;
String activity =null;
int sourceId = -1;
int targetId = -1;
int nodeIndex = 0;
int targetIndex = -1;
JSONObject jsonLine = null;
// Iterate over the Map of links
for(Integer index : this.links.keySet()){
// gather information needed for Json object
Link link = this.links.get(index);
// nodes need
sourceId = link.getSourceId();
targetId = link.getTargetId();
forename = people.getValue(link.getSourceId()).getForenames();
surname = people.getValue(link.getSourceId()).getSurname();
linkSourceActivity = link.getSourceActivityCode();
//If source node doesn't exist, create it
if(!sourceMap.containsKey(sourceId)){
// Create a node and add to array
jsonLine = new JSONObject();
jsonLine.put("name",forename+ " " +surname);
jsonLine.put("group", linkSourceActivity);
jsonLine.put("role", "Director");
nodes.add(jsonLine);
// add entry to map
sourceMap.put(sourceId, nodeIndex);
nodeIndex++;
}
forename = people.getValue(link.getTargetId()).getForenames();
surname = people.getValue(link.getTargetId()).getSurname();
linkTargetActivity = link.getTargetActivityCode();
activity = link.getTargetActivity();
targetIndex = (targetId * 0x1f1f1f1f) ^ linkTargetActivity;
// If the target node doesn't exist, create it
if(!targetMap.containsKey(targetIndex)){
jsonLine = new JSONObject();
jsonLine.put("name", forename+ " " +surname);
jsonLine.put("group", linkTargetActivity);
jsonLine.put("role", activity);
nodes.add(jsonLine);
// add entry to map
targetMap.put(targetIndex, nodeIndex);
nodeIndex++;
}
// links need
// source (position in node array)
// target (position in node array)
int sourcePos = sourceMap.get(sourceId);
int targetPos = targetMap.get(targetIndex);
int value = link.getMultiplicity();
// Build the array of play titles for this Link
List<Integer> productionIds = link.getProductions();
JSONArray playTitles = new JSONArray();
int playId = -1;
String playName = null;
for (Integer Id : productionIds){
playId = productions.getValue(Id).getPlayId();
playName = plays.getValue(playId).getMainTitle();
// don't include duplicate titles
if(!playTitles.contains(playName)){
playTitles.add(plays.getValue(playId).getMainTitle());
}
}
JSONObject linkLine = new JSONObject();
linkLine.put("source", sourcePos);
linkLine.put("target", targetPos);
linkLine.put("value", value);
linkLine.put("plays", playTitles);
links.add(linkLine);
} // end iterate over Links
obj.put("nodes", nodes);
obj.put("links", links);
return obj;
} // end getJson method
// Method to write Json to a file
public void writeJson(String path){
try {
FileWriter file = new FileWriter(path);
file.write(jsonLinks.toJSONString());
file.flush();
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} // end JsonOutput
Yes, org.json.JSONArray does not have a method put(..). See the JavaDoc.
You could use public JSONArray put(java.lang.Object value).
Was using the wrong library, code works fine with JSONsimple ! :)
I am working on a very simple application for a website, just a basic desktop application.
So I've figured out how to grab all of the JSON Data I need, and if possible, I am trying to avoid the use of external libraries to parse the JSON.
Here is what I am doing right now:
package me.thegreengamerhd.TTVPortable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import me.thegreengamerhd.TTVPortable.Utils.Messenger;
public class Channel
{
URL url;
String data;
String[] dataArray;
String name;
boolean online;
int viewers;
int followers;
public Channel(String name)
{
this.name = name;
}
public void update() throws IOException
{
// grab all of the JSON data from selected channel, if channel exists
try
{
url = new URL("https://api.twitch.tv/kraken/channels/" + name);
URLConnection connection = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
data = new String(in.readLine());
in.close();
// clean up data a little, into an array
dataArray = data.split(",");
}
// channel does not exist, throw exception and close client
catch (Exception e)
{
Messenger.sendErrorMessage("The channel you have specified is invalid or corrupted.", true);
e.printStackTrace();
return;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < dataArray.length; i++)
{
sb.append(dataArray[i] + "\n");
}
System.out.println(sb.toString());
}
}
So here is what is printed when I enter an example channel (which grabs data correctly)
{"updated_at":"2013-05-24T11:00:26Z"
"created_at":"2011-06-28T07:50:25Z"
"status":"HD [XBOX] Call of Duty Black Ops 2 OPEN LOBBY"
"url":"http://www.twitch.tv/zetaspartan21"
"_id":23170407
"game":"Call of Duty: Black Ops II"
"logo":"http://static-cdn.jtvnw.net/jtv_user_pictures/zetaspartan21-profile_image-121d2cb317e8a91c-300x300.jpeg"
"banner":"http://static-cdn.jtvnw.net/jtv_user_pictures/zetaspartan21-channel_header_image-7c894f59f77ae0c1-640x125.png"
"_links":{"subscriptions":"https://api.twitch.tv/kraken/channels/zetaspartan21/subscriptions"
"editors":"https://api.twitch.tv/kraken/channels/zetaspartan21/editors"
"commercial":"https://api.twitch.tv/kraken/channels/zetaspartan21/commercial"
"teams":"https://api.twitch.tv/kraken/channels/zetaspartan21/teams"
"features":"https://api.twitch.tv/kraken/channels/zetaspartan21/features"
"videos":"https://api.twitch.tv/kraken/channels/zetaspartan21/videos"
"self":"https://api.twitch.tv/kraken/channels/zetaspartan21"
"follows":"https://api.twitch.tv/kraken/channels/zetaspartan21/follows"
"chat":"https://api.twitch.tv/kraken/chat/zetaspartan21"
"stream_key":"https://api.twitch.tv/kraken/channels/zetaspartan21/stream_key"}
"name":"zetaspartan21"
"delay":0
"display_name":"ZetaSpartan21"
"video_banner":"http://static-cdn.jtvnw.net/jtv_user_pictures/zetaspartan21-channel_offline_image-b20322d22543539a-640x360.jpeg"
"background":"http://static-cdn.jtvnw.net/jtv_user_pictures/zetaspartan21-channel_background_image-587bde3d4f90b293.jpeg"
"mature":true}
Initializing User Interface - JOIN
All of this is correct. Now what I want to do, is to be able to grab, for example the 'mature' tag, and it's value. So when I grab it, it would be like as simple as:
// pseudo code
if(mature /*this is a boolean */ == true){ // do stuff}
So if you don't understand, I need to split away the quotes and semicolon between the values to retrieve a Key, Value.
It's doable with the following code :
public static Map<String, Object> parseJSON (String data) throws ParseException {
if (data==null)
return null;
final Map<String, Object> ret = new HashMap<String, Object>();
data = data.trim();
if (!data.startsWith("{") || !data.endsWith("}"))
throw new ParseException("Missing '{' or '}'.", 0);
data = data.substring(1, data.length()-1);
final String [] lines = data.split("[\r\n]");
for (int i=0; i<lines.length; i++) {
String line = lines[i];
if (line.isEmpty())
continue;
line = line.trim();
if (line.indexOf(":")<0)
throw new ParseException("Missing ':'.", 0);
String key = line.substring(0, line.indexOf(":"));
String value = line.substring(line.indexOf(":")+1);
if (key.startsWith("\"") && key.endsWith("\"") && key.length()>2)
key = key.substring(1, key.length()-1);
if (value.startsWith("{"))
while (i+1<line.length() && !value.endsWith("}"))
value = value + "\n" + lines[++i].trim();
if (value.startsWith("\"") && value.endsWith("\"") && value.length()>2)
value = value.substring(1, value.length()-1);
Object mapValue = value;
if (value.startsWith("{") && value.endsWith("}"))
mapValue = parseJSON(value);
else if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false"))
mapValue = new Boolean (value);
else {
try {
mapValue = Integer.parseInt(value);
} catch (NumberFormatException nfe) {
try {
mapValue = Long.parseLong(value);
} catch (NumberFormatException nfe2) {}
}
}
ret.put(key, mapValue);
}
return ret;
}
You can call it like that :
try {
Map<String, Object> ret = parseJSON(sb.toString());
if(((Boolean)ret.get("mature")) == true){
System.out.println("mature is true !");
}
} catch (ParseException e) {
}
But, really, you shouldn't do this, and use an already existing JSON parser, because this code will break on any complex or invalid JSON data (like a ":" in the key), and if you want to build a true JSON parser by hand, it will take you a lot more code and debugging !
This is a parser of an easy json string:
public static HashMap<String, String> parseEasyJson(String json) {
final String regex = "([^{}: ]*?):(\\{.*?\\}|\".*?\"|[^:{}\" ]*)";
json = json.replaceAll("\n", "");
Matcher m = Pattern.compile(regex).matcher(json);
HashMap<String, String> map = new HashMap<>();
while (m.find())
map.put(m.group(1), m.group(2));
return map;
}
Live Demo