Keep the Order of the Json Keys During Json Conversion to Csv

Keep the order of the JSON keys during JSON conversion to CSV

Solved.

I used the JSON.simple library from here https://code.google.com/p/json-simple/ to read the JSON string to keep the order of keys and use JavaCSV library from here http://sourceforge.net/projects/javacsv/ to convert to CSV format.

How to keep the order of org.json.JSONObject?

finally, I use the alibaba.json to contains the order of JsonObject.
and Then I overwrite the org.json's CDL.toString by alibaba.json lib.

package com._4paradigm.repservice.utils;
import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import org.apache.commons.io.FileUtils;
import java.io.File;import java.io.IOException;import java.util.LinkedHashMap;import java.util.Set;
public class ConvertCsv { public ConvertCsv() { } public static String toString(JSONArray ja) {
JSONObject jo = ja.getJSONObject(0); if (jo != null) { Set<String> strings = jo.keySet(); JSONArray names = JSONArray.parseArray(JSON.toJSONString(strings)); if (names != null) { return rowToString(names) + toString(names, ja); } }
return null; } public static String rowToString(JSONArray jsonArray) { StringBuilder sb = new StringBuilder();
for(int i = 0; i < jsonArray.size() ; ++i) { if (i > 0) { sb.append(','); } Object object = jsonArray.get(i); if (object != null) { String string = object.toString();// System.out.println(string); if (string.length() > 0 && (string.indexOf(44) >= 0 || string.indexOf(10) >= 0 || string.indexOf(13) >= 0 || string.indexOf(0) >= 0 || string.charAt(0) == '"')) { sb.append('"'); int length = string.length();
for(int j = 0; j < length; ++j) { char c = string.charAt(j); if (c >= ' ' && c != '"') { sb.append(c); } }
sb.append('"'); } else { sb.append(string); } } }
sb.append('\n'); return sb.toString(); }
public static String toString(JSONArray names, JSONArray ja) { if (names != null && names.size() != 0) { StringBuilder sb = new StringBuilder();
for(int i = 0; i < ja.size(); ++i) { JSONObject jo = ja.getJSONObject(i); if (jo != null) { sb.append(rowToString(toJSONArray(jo, names))); } }
return sb.toString(); } else { return null; } } public static JSONArray toJSONArray(JSONObject obj, JSONArray names) { if (names != null && !names.isEmpty()) { JSONArray ja = new JSONArray();
for(int i = 0; i < names.size(); ++i) { ja.add(obj.get(names.getString(i))); }
return ja; } else { return null; } }

public static void main(String[] args) throws IOException { JSONArray array = new JSONArray(); JSONObject object2 = new JSONObject(new LinkedHashMap<>()); object2.put("name","LiMing"); object2.put("age","28"); object2.put("gender","man");
JSONObject object = new JSONObject(new LinkedHashMap<>()); object.put("name","LiPing"); object.put("age","26"); object.put("gender","women");
array.add(object); array.add(object2);
String s = ConvertCsv.toString(array);
FileUtils.writeStringToFile(new File("E:\\hello.csv"), s); }}

How to maintain the order of a JSONObject

You can't.

That is why we call it an unordered collection of name/value pairs.

Why you would need to do this, I'm not sure. But if you want ordering, you'll have to use a json array.

Keeping JSON file keys in order with org.json?

If you want to preserve the order of keys in a map, you should not use JSON. The order of keys in a map is semantically meaningless in JSON.

JSON to CSV, skipping certain columns and re-ordering others - Ruby

Here is the code that works:

require 'csv'
require 'json'
require 'set'

def get_recursive_keys(hash, nested_key=nil)
hash.each_with_object([]) do |(k,v),keys|
# Col filter
next if ["score", "original_name"].include? k
k = "#{nested_key}.#{k}" unless nested_key.nil?
if v.is_a? Hash
keys.concat(get_recursive_keys(v, k))
else
keys << k
end
end
end

json = JSON.parse(File.open(ARGV[0]).read)
headings = Set.new
headings = get_recursive_keys(json)

headings = headings.to_a
# Header sorting
headings = headings.sort { |a, b| a <=> b }


CSV.open(ARGV[0] + '.csv', 'w') do |csv|
csv << headings
row = headings.map do |h|
v = (h.split('.').length > 1) ? json.dig(*h.split('.')) : h
v.is_a?(Array) ? v.join(',') : v
end
csv << row
end

I tested with this small json string: {"score": "12", "name": "Obi", "original_name": "Wan Kenobi", "something": {"sub_key": "Wuhu"} }

Get all JSON keys in the order they are defined in the file

From JSON RFC7159:

An object is an unordered collection of zero or more name/value pairs [...]

Consequently, the API you are asking for would return more information than actually contained in the JSON object. This behaviour would therefore not comply with the standard.

If you really need an ordering of your JSON objects, you can always express the information in a JSON compliant way by using arrays instead of objects:

{"first":1, "second":2} // Unordered
[{key:"first",value:1}, {key:"second",value:2}] // Ordered

Another motivation for expressing the information as arrays is that keys might change. Most NoSQL databases are capable of creating indexes on object attributes (e.g. MongoDB) and the normalization above is usually the best way to go, even when an ordering is not required

However, if desired, the map you are looking for can still be created as a temporary index for efficient access of JSON objects by looking them up using a specific key.

Does the StringBuffer change the order of JSON?

It's not the StringBuffer but the JSONArray.

The order of elements in an array [] is maintained like the list ["AUT","FRA","SMR","SVN","CHE","VAT"] in both examples.

Anything as a name value pair surrounded by {} can be reordered like {"code":"EUR","name":"Euro","symbol":"€"} and {"symbol":"\u20ac","code":"EUR","name":"Euro"}.

To prevent this, you can keep it as a String or create your own object and define the toString method.



Related Topics



Leave a reply



Submit