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>
smac
  • 23
  • 2
  • 6
  • https://stackoverflow.com/a/19978281/3830694 – Krupal Shah Jun 04 '19 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 – msrd0 Jun 04 '19 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. – smac Jun 04 '19 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. – msrd0 Jun 04 '19 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) – smac Jun 04 '19 at 20:46
  • Underscore-java library has a static method U.jsonToXml(json) – Valentyn Kolesnikov Feb 10 '23 at 05:05

2 Answers2

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

maxemann96
  • 91
  • 1
  • 8
  • 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. – smac Jun 04 '19 at 18:45
  • I updated my answer for your updated question, this should fix this error – maxemann96 Jun 04 '19 at 20:54
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.

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • 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 Jun 04 '19 at 18:48
  • @smac Seems you changed it back, so which is it? – Andreas Jun 04 '19 at 21:07
  • 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) – smac Jun 05 '19 at 12:40