I need to parse list of json stored in a single file !
What I have done so far is,
test.json file contains:
{"location":"lille","lat":28.4,"long":51.7,"country":"FR"}
with this file I have the code below
public class JsonReader {
public static void main(String[] args) throws ParseException {
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("c:\\test.json"));
JSONObject locationjson= (JSONObject) obj;
String location= (String) locationjson.get("location");
System.out.printf("%s",location);
long lat = (Long) locationjson.get("lat");
System.out.printf("\t%d",lat);
//similarly for other objects
This is a working code and I am able to print only one json in the file test.json
Now if I have to print a list of json in file: test1.json as shown below: each line is a single valid json and there are list of json in a single file. What I need is to parse each json and print it in each line. Will using a bean class work?
{"Atlas":{"location":"lille","lat":28.4,"long":51.7,"country":"FR"}}
{"Atlas":{"location":"luxum","lat":24.1,"long":54.7,"country":"LU"}}
{"Atlas":{"location":"ghent","lat":28.1,"long":50.1,"country":"BE"}}
{"Atlas":{"location":"alborg","lat":23.4,"long":53.7,"country":"DN"}}
Your help is appreciated !
The JSON should have a root node.
If you don't have that, you can read from the file line-by-line, and pass each line into the JSONParser wrapped in a StringReader (since the JSONParser.parse() method takes a Reader).
e.g.
BufferedReader in
= new BufferedReader(new FileReader("test.json"));
while(!done) {
String s = in.readLine();
if (s == null) {
done = true;
}
else {
StringReader sr = new StringReader(s);
// etc...
}
}
Edit: I've assumed you're using JSONParser. If you're using a different parser (which one?) then it may take a String argument.
JSONParser.parse() also takes the String as an aurgument.
Read the file with FileReader and for each line that you read use JSONParser.parse(String) method.
First of all:make sure you have created a class just for the son item for each row that has the string properties in the header file and synthesized in the implementation file.Then create a property array in the implementation file that will be doing the parsing.In the parse file..use NSJSONSerialization in your retrieve data method:
-(void)retrieveData{
NSURL * url =[NSURL URLWithString:getDataURL];
NSData *data =[NSData dataWithContentsOfURL:url];
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
newsArray = [[NSMutableArray alloc]init];
for (int i = 0; i < json.count; i++){
{
NSString * cID =[[json objectAtIndex:i]objectForKey:#"Name1"];
NSString * cName = [[json objectAtIndex:i]objectForKey:#"name2"];
NSString * cState =[[json objectAtIndex:i]objectForKey:#"name3"];
NSString * cPopulation =[[json objectAtIndex:i]objectForKey:#"Edition"];
NSString * cCountry =[[json objectAtIndex:i]objectForKey:#"name4"];
City *myCity = [[City alloc]initWithCityID:cID andCityName:cName andCityState:cState andCityPopulation:cPopulation andCityCountry:cCountry];
[newsArray addObject:myCity];
}
[self.myTableView reloadData];
}
}
Then retrieve the son objects or arrays and enter them in the name 1 name 2 section to parse them to your table.Also make sure you have already setup your Table and assigned it a cell identifier and indexed to row.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//static NSString *strIdentifier=#"identity";
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
// cell.textLabel.text = [NSString stringWithFormat:#"Cell %d",indexPath.row];
City *currentCity =[newsArray objectAtIndex:indexPath.row];
cell.textLabel.text = currentCity.Name1;
cell.detailTextLabel.text = currentCity.Name2;
return cell;
}
Related
I am writing a program that generates PDF files of printable exams. I have all the exam questions stored in a JSON file. The catch is that the exam is in Czech, so there are many special characters (specifically ěščřžýáíé). When I run the program in Idea, it works perfectly - the output is exactly as it is supposed to be.
But when I build the jar executable, the generated files have chunks of wrong encoded text. Specifically anything that went through the JSON parser. Everything hard coded like headers etc. is encoded properly, so the mistake must be in the parser.
The JSON input file is encoded in UTF-8.
I use these two methods to parse the JSON file.
private static Category[] parseJSON(){
JSONParser jsonParser = new JSONParser();
Category[] categories = new Category[0];
try (FileReader reader = new FileReader("otazky.json")){
// Read JSON file
Object obj = jsonParser.parse(reader);
JSONArray categoryJSONList = (JSONArray) obj;
java.util.List<JSONObject> categoryList = new ArrayList<>(categoryJSONList);
categories = new Category[categoryJSONList.size()];
int i = 0;
for (JSONObject category : categoryList) {
categories[i] = parseCategoryObject(category);
i++;
}
} catch (ParseException | IOException e) {
e.printStackTrace();
}
return categories;
}
private static Category parseCategoryObject(JSONObject category) {
String categoryName = (String) category.get("name");
int generateCount = (int) (long) category.get("generateCount");
JSONArray questionsJSONArray = (JSONArray) category.get("questions");
java.util.List<JSONObject> questionJSONList = new ArrayList<>(questionsJSONArray);
Question[] questions = new Question[questionJSONList.size()];
int j = 0;
for (JSONObject question : questionJSONList) {
JSONArray answers = (JSONArray) question.get("answers");
String s = (String) question.get("question");
String[] a = new String[answers.size()];
for (int i = 0; i < answers.size(); i++) {
a[i] = answers.get(i).toString();
}
int c = (int) (long) question.get("correct");
Question q = new Question(s, a, c);
questions[j] = q;
j++;
}
return new Category(categoryName, questions, generateCount);
}
The output looks like this:
...
Právnà norma:
a) je obecnÄ› závaznĂ© pravidlo chovánĂ, kterĂ© nemusĂ mĂt urÄŤitou formu,
b) nemĹŻĹľe bĂ˝t součástĂ právnĂho pĹ™edpisu,
...
While I would need it to look like this:
...
Právní norma:
a) je obecně závazné pravidlo chování, které nemusí mít určitou formu,
b) nemůže být součástí právního předpisu,
...
Benjamin Urquhart suggested that I try using InputStringReader and FileInputStream instead of FileReader to read the file, because with FileReader you cannot specify the encoding (system default is used). I find those two methods hard to use, but I found an alternative - Files.readAllLines, which is fairly easy to use, and it worked.
I would like to read a hdfs folder containing avro files with spark . Then I would like to deserialize the avro events contained in these files. I would like to do it without the com.databrics library (or any other that allow to do it easely).
The problem is that I have difficulties with the deserialization.
I assume that my avro file is compressed with snappy because at the begining of the file (just after the schema), I have
avro.codecsnappy
written. Then it's followed by readable or unreadable charaters.
My first attempt to deserialize the avro event is the following :
public static String deserialize(String message) throws IOException {
Schema.Parser schemaParser = new Schema.Parser();
Schema avroSchema = schemaParser.parse(defaultFlumeAvroSchema);
DatumReader<GenericRecord> specificDatumReader = new SpecificDatumReader<GenericRecord>(avroSchema);
byte[] messageBytes = message.getBytes();
Decoder decoder = DecoderFactory.get().binaryDecoder(messageBytes, null);
GenericRecord genericRecord = specificDatumReader.read(null, decoder);
return genericRecord.toString();
}
This function works when I want to deserialise an avro file that doesn't have the avro.codecsbappy in it. When it's the case I have the error :
Malformed data : length is negative : -50
So I tried another way of doing it which is :
private static void deserialize2(String path) throws IOException {
DatumReader<GenericRecord> reader = new GenericDatumReader<>();
DataFileReader<GenericRecord> fileReader =
new DataFileReader<>(new File(path), reader);
System.out.println(fileReader.getSchema().toString());
GenericRecord record = new GenericData.Record(fileReader.getSchema());
int numEvents = 0;
while (fileReader.hasNext()) {
fileReader.next(record);
ByteBuffer body = (ByteBuffer) record.get("body");
CharsetDecoder decoder = Charsets.UTF_8.newDecoder();
System.out.println("Positon of the index " + body.position());
System.out.println("Size of the array : " + body.array().length);
String bodyStr = decoder.decode(body).toString();
System.out.println("THE BODY STRING ---> " bodyStr);
numEvents++;
}
fileReader.close();
}
and it returns the follwing output :
Positon of the index 0
Size of the array : 127482
THE BODY STRING --->
I can see that the array isn't empty but it just return an empty string.
How can I proceed ?
Use this when converting to string:
String bodyStr = new String(body.array());
System.out.println("THE BODY STRING ---> " + bodyStr);
Source: https://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/
Well, it seems that you are on a good way. However, your ByteBuffer might not have a proper byte[] array to decode, so let's try the following instead:
byte[] bytes = new byte[body.remaining()];
buffer.get(bytes);
String result = new String(bytes, "UTF-8"); // Maybe you need to change charset
This should work, you have shown in your question that ByteBuffer contains actual data, as given in the code example you might have to change the charset.
List of charsets: https://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html
Also usful: https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html
I am trying to loop through a JSON file and append the value each time to patientList. So far I believe I have done the hard part, however the simplest part seems to be taking a lot of time, that is appending the values to patientList. My getJsonFile method gets the path of the JSON file. The format of the JSON file is below. I am able to print jsonArray so I know I am good up to that point, but lost after that.
Json file.
[{"patient":1},{"patient":2},{"patient":3},{"patient":4},{"patient":5},{"patient":6},{"patient":7},{"patient":8},{"patient":9}]
getJsonFile method.
private List<Integer> getJsonFile(String path)
{
List<Integer> patientList = new ArrayList<>();
try (FileReader reader = new FileReader(path))
{
JSONParser jsonParser = new JSONParser();
JSONArray jsonArray = (JSONArray)jsonParser.parse(reader);
System.out.println(jsonArray);
// Update patientList
for (int i = 0; i < jsonArray.size(); i++ )
{
patientList.add(jsonArray(i));
}
}
catch(IOException | ParseException | NullPointerException e)
{
e.printStackTrace();
}
return patientList;
}
Your JSONArray contains objects: {"patient":1}
So you could not add patientList.add(jsonArray(i));
You have to access the int value inside that object:
JSONObject patient = jsonArray.getJsonObject(i);
patientList.add(patient.getInt("patient");
Edit
Well. You are using the simple-json library with quite limit feature and outdated. In this case you have to cast the data yourself:
JSONObject patient = (JSONObject)jsonArray.get(i);
patientList.add((Integer)patient.get("patient");
I recommend you remove this lib and use existing JSON feature of Java. If you want more advance feature, Jackson/GSon is the library to use.
I'm trying to generate a json file from my data but I end up generating only one json object before I get this exception Java Cannot generate more than one JSON text
This is my code:
OutputStream fos = new FileOutputStream("new_fake_students.json",false);
JsonGenerator g = Json.createGenerator(fos);
while (matcher.find())
{
String temp = matcher.group();
String[] values = temp.split(",");
if(values.length>=4)
{
g.writeStartObject();
g.write("id",values[0]);
g.write("name",values[1]+values[2]);
g.write("major",values[3]);
g.writeEnd();
}
}
g.close();
fos.close();
}
As it seems that you generate more than one object, are you sure you don't want to generate an array of objects? Perhaps:
OutputStream fos = new FileOutputStream("new_fake_students.json",false);
JsonGenerator g = Json.createGenerator(fos);
g.writeStartArray(); // start the array
while (matcher.find())
{
String temp = matcher.group();
String[] values = temp.split(",");
if(values.length>=4)
{
g.writeStartObject();
g.write("id",values[0]);
g.write("name",values[1]+values[2]);
g.write("major",values[3]);
g.writeEndObject(); // does g.writeEnd() even exists?
}
}
g.writeEndArray(); // close that array
I need to export the values in 4 column.values for 3 columns are populating properly.
I am having trouble with 4th column which is organization column.it is multivalued column.i.e.: it has multiple values.
I have tried to convert from object to String for organization column but didnt help.
Please see the code below:
String appname = "abc";
String path = "//home/exportfile//";
String filename = path+"ApplicationExport-"+appname+".txt";
String ret = "false";
QueryOptions ops = new QueryOptions();
Filter [] filters = new Filter[1];
filters[0] = Filter.eq("application.name", appname);
ops.add(filters);
List props = new ArrayList();
props.add("identity.name");
//Do search
Iterator it = context.search(Link.class, ops, props);
//Build file and export header row
BufferedWriter out = new BufferedWriter(new FileWriter(filename));
out.write("Name,UserName,WorkforceID,organization");
out.newLine();
//Iterate Search Results
if (it!=null)
{
while (it.hasNext()) {
//Get link and create object
Object [] record = it.next();
String identityName = (String) record[0];
Identity user = (Identity) context.getObject(Identity.class, identityName);
//Get Identity attributes for export
String workforceid = (String) user.getAttribute("workforceID");
//Get application attributes for export
String userid="";
List links = user.getLinks();
if (links!=null)
{
Iterator lit = links.iterator();
while (lit.hasNext())
{
Link l = lit.next();
String lname = l.getApplicationName();
if (lname.equalsIgnoreCase(appname))
{
userid = (String) l.getAttribute("User Name");
List orgList = l.getAttribute("Organization");
}
}
}
//Output file
out.write(identityName+","+userid+","+workforceid+","+org);
out.newLine();
out.flush();
}
ret="true";
}
//Close file and return
out.close();
return ret;
The output of this code should be:
for ex:
Name,UserName,WorkforceID,organization
abc,abc,123,xy
qwe,q01,234,xy
any help correcting this code will be greatly appreciated.
EDIT:
This should give you the output you want:
out.write(identityName+","+userid+","+workforceid+","+Arrays.toString(orgList.toArray());
you probably want to declare List orgList outside the while loop since everytime it is being created and also you are using org and i havent seen any org elsewhere in your code