0

How do I output all the JSON lines into one XML output? My code only outputs the first JSON line.

I have a data file that contains several JSON lines in them (CR & LF at end of each JSON line):

{"valueName":"GPS_latitude","valueType":"-1","value":"39.26842508","objectID":"charger_80","timestamp":"1556841594000"}
{"valueName":"GPS_longitude","valueType":"-1","value":"-76.60410104","objectID":"charger_80","timestamp":"1556841594000"}
{"valueName":"GPS_altitude","valueType":"-1","value":"13","objectID":"charger_80","timestamp":"1556841594000"}

My java src looks like:

import org.json.JSONObject; 
import org.json.XML;

//Reads in the file and makes it one big string (which works correctly) 
String jsonData = readFile("testfilePD.json");

//Converts the JSON string into XML but stops after first line. 
String jsonBody = Convert_JSON_TO_XML.convert_json(jsonData); System.out.println(jsonBody);

//I'm using the XML library to convert    
public static String convert_json(String json_value) {
    String xml = "<node>";
    try {
        JSONObject jsoObject = new JSONObject(json_value);
        xml = xml + XML.toString(jsoObject);
    } catch (Exception e) {
        System.out.println(e);
    }
    xml = xml + "</node>";
    return xml;
}

Or, is there a better JSON to XML conversion library? Or how do I modify the XML library to read my entire file and output them in one big XML file correctly. I'm eventually sending this xml file to a web service API for ingestion. I'm stuck.

Output should be something like:

<?xml version="1.0"?>
<node>
<valueName>GPS_latitude</valueName>
<valueType>-1</valueType>
<value>39.26842508</value>
<objectID>charger_80</objectID>
<timestamp>1556841594000</timestamp>
</node>
<node>
<valueName>GPS_longitude</valueName>
<valueType>-1</valueType>
<value>-76.60410104</value>
<objectID>charger_80</objectID>
<timestamp>1556841594000</timestamp>
</node>
6
  • stackoverflow.com/a/19978281/3830694 Commented Jun 4, 2019 at 17:26
  • Do you have influence on the provided source file? Because currently, your input is not valid JSON, however you could easily build a JSON Array by appending a '[', ending every line with a , and place a ] at the end of the file Commented Jun 4, 2019 at 17:38
  • I am not able to influence the source file. It is coming from a piece of GPS equipment and needs to be converted to XML (if I need to add node0, node1, etc. to the XML output, that is ok)...just having trouble converting past the first JSON line. Commented Jun 4, 2019 at 19:17
  • Well, given your updated question, it's a lot more complicated since the independent json objects are now no longer newline separated. Commented Jun 4, 2019 at 20:35
  • Actually, I just checked in notepad++ and saw that each JSON line has a CR LF char at the end. I adjusted the input file to look like it should (my IDE (intellij) was displaying it as JSON) Commented Jun 4, 2019 at 20:46

2 Answers 2

2

This should solve your problem:

import org.json.JSONArray;
import org.json.JSONTokener;
import org.json.XML;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class ConvertExample {
    public static void main(String[] args) throws IOException {
        JSONTokener tokener = new JSONTokener(Files.newInputStream(Paths.get("test.json")));
        JSONArray array = new JSONArray();

        while(tokener.nextClean() != '\u0000'){
            tokener.back();
            array.put(tokener.nextValue());
        }

        // Print XML with each array entry named node
        System.out.println(XML.toString(array, "node"));
    }
}

Updated for updated question Here a JSONTokener is used to tokenize it top bottom. The loop checks whether the tokenizer is at end of file and if not, go a step back (unread the char) and parses the next value

Sign up to request clarification or add additional context in comments.

2 Comments

Using the above, I get an exception 'Exception in thread "main" org.json.JSONException: A JSONObject text must end with '}' at 2 [character 3 line 1]' So, the JSON array is [0] = '{', [1] = 'value':'GPS_latitude', etc.
I updated my answer for your updated question, this should fix this error
0

That is not a JSON file, so you can't use new JSONObject(json_value) where json_value is the entire content of the file.

The file is a list of JSON texts, one per line, so you need to read each line separately, e.g. using BufferedReader, and parse each line separately, producing a JSONObject[].

Then you need to decide whether each separate JSON text becomes a separate root XML element, or if the XML is combined.


UPDATE: To read and convert to XML, you can do it like this:

StringBuilder buf = new StringBuilder();
Files.lines(Paths.get("testfilePD.json")).forEach(line -> {
    JSONObject jsoObject = new JSONObject(line);
    buf.append(XML.toString(jsoObject, "node"))
       .append(System.lineSeparator());
});
System.out.println(buf.toString());

Output

<node><valueName>GPS_latitude</valueName><valueType>-1</valueType><value>39.26842508</value><objectID>charger_80</objectID><timestamp>1556841594000</timestamp></node>
<node><valueName>GPS_longitude</valueName><valueType>-1</valueType><value>-76.60410104</value><objectID>charger_80</objectID><timestamp>1556841594000</timestamp></node>
<node><valueName>GPS_altitude</valueName><valueType>-1</valueType><value>13</value><objectID>charger_80</objectID><timestamp>1556841594000</timestamp></node>

Note that the generated XML is as invalid as the original JSON, since both have more than one root element/object.

3 Comments

You are right Andres, when I look at the JSON file in my IDE, I get a 'JSON standard allows only one top-level value' error. The file is from a piece of GPS equipment so can't be changed. How would I go about creating each individual JSONObject from those lines?
@smac Seems you changed it back, so which is it?
Actually, I just checked in notepad++ and saw that each JSON line has a CR LF char at the end. I adjusted the input file to look like it should (my IDE (intellij) was displaying it as JSON)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.