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
Java Ssl: How to Disable Hostname Verification
Avoid Keycloak Default Login Page and Use Project Login Page
How to Know Which Tomcat Version Embedded in Spring Boot
Add Additional Rules to the Compare Method of a Comparator
How to Exclude Classes from Test Coverage Using Java Annotations in Spring Boot
How to Get Response as Json With Responseentity in Java
Using Loop to Accept Additional User Input Until User Enters a Value That Ends the Input
Spring Boot Not Recognizing Application.Properties File
Server_Error: [Code] 1675030 [Message]: Error Performing Query
How to Truncate a Double to Only Two Decimal Places in Java
Java Error Message. Unexpected Type, Required Variable, Found Value
How to Exclude an Android App from Battery Optimization Using Code
Filling a List With All Enum Values in Java
Kafka: How to Delete Records from a Topic Using Java API
Check If Url Is Https or Http Protocol
Hibernate Error - Querysyntaxexception: Users Is Not Mapped [From Users]
Simpledateformat Producing Wrong Date Time When Parsing "Yyyy-Mm-Dd Hh:Mm"