我使用JSON in Java将XML转换为JSON。我有这个实现正在反转所有子元素的问题。
当我传递这个XML时:
<Person><Child1>a</Child1><Child2>b</Child2></Person>
我最终会得到一个孩子倒置的JSON:
{"Person":{"Child2":"b", "Child1":"a"}}
我的Java代码:
JSONObject jsonObject= XML.toJSONObject("<Person><Child1>a</Child1><Child2>b</Child2></Person>");
String myJSONString = jsonObject.toString(4);
如何通过保持元素的顺序(如XML)转换为JSON?
答案 0 :(得分:9)
所以我的问题。如何在保持顺序的情况下转换为JSON?
目前的官方JSONObject,这是不可能的。 API非常清楚:
JSONObject是名称/值对的无序集合。
但,您的问题可能会有一个快速的解决方法。正如我在JSONObject source code中所调查的那样,您可以看到它在内部使用HashMap,并且您知道HashMap不会保留任何顺序。
public JSONObject() {
this.map = new HashMap<String, Object>();
}
您有两种选择:
修改当前的JSONObject源代码,以便使用LinkedHashMap初始化地图。 LinkedHashMap是 Map接口的一个实现,具有可预测的迭代顺序:
public JSONObject() {
this.map = new LinkedHashMap<String, Object>();
}
创建自己的自定义类,扩展JSONObject但在内部使用LinkedHashMap。请注意,您仍然需要在JSONObject中进行一些更改。
public class JSONObject {
//private final Map<String,Object> map; // current approach
//you have to remove final modifier and either add a getter or make it protected. I'll choose the change modifier to protected in this case.
protected Map<String,Object> map;
}
public class JSONObjectOrdered extends JSONObject {
public JSONObjectOrdered(){
this.map = new LinkedHashMap <String, Object>();
}
}
答案 1 :(得分:0)
JSON对象没有特定的订单。您当然可以更改序列化实现以保持订单,但无法保证在反序列化后也保留它。实际上,大多数JSON库甚至没有API来检测原始JSON文本的解析顺序。在使用对象时,您不应该关心订购。
如果您确实关心订单,请使用JSON数组。
{"Person":[{"Child1":"a"},{"Child2":"b"}]}
答案 2 :(得分:0)
JSONObject API不保证元素顺序 这个问题的一个很好的解决方案是使用JSONArray,在JSONArray中保存插入元素的顺序。
所以,在你的情况下,每个人都会有一系列的“chides”。 您可能需要更改XML文件或手动将XML解析为您格式的json(JSONArray而不是您现在使用的内容)
答案 3 :(得分:0)
如果你一直想按照你想要的方式输出输出,你总是可以尝试覆盖方法
toString()
答案 4 :(得分:0)
由于JSONObject是一个无序的名称/值对集合,没有选择,你必须使用JSONArray。
这是我的解决方案,修改XML
类,特别是方法parse
,以便返回JSONArray
来存储子节点。
我修改过的课程:XML.java
XML输入
<Person name="test"><Child1>a</Child1><Child2>b</Child2><Child3></Child3></Person>
用法:
JSONObject jsonObject= XML.toJSONObject("<Person name=\"test\"><Child1>a</Child1><Child2>b</Child2><Child3></Child3></Person>");
System.out.println(jsonObject);
出:
{"Person":{"CHILDREN":[{"Child1":"a"},{"Child2":"b"},{"Child3":""}],"name":"test"}}
<强>结论强>
保留儿童令。当然,这个想法可以改进,它只是一个关于可以做什么的POC,修改解析器。
答案 5 :(得分:0)
您可以从http://www.json.org/java/下载源代码,并使用TreeMap而不是HashMap修改JSONObject.java。
您还可以覆盖JSONObject.java中的方法
public Iterator<String> keys() {
return this.keySet().iterator();
}
确保Iterator是排序键之一。
答案 6 :(得分:0)
如果您使用Jackson进行JSON序列化/反序列化,您可以简单地添加一个 @JsonPropertyOrder()注释在你的课程之上。
@JsonPropertyOrder({"Child1", "Child2"})
public class Person {
@JsonProperty("Child1")
public String child1;
@JsonProperty("Child2")
public String child2;
}
答案 7 :(得分:-1)
修改时可以保持传入数据的顺序
private final Map<String, Object> nameValuePairs;
/**
* Creates a {@code JSONObject} with no name/value mappings.
*/
public JSONObject() {
nameValuePairs = new HashMap<String, Object>();
}
到
private final Map<String, Object> nameValuePairs;
/**
* Creates a {@code JSONObject} with no name/value mappings.
*/
public JSONObject() {
nameValuePairs = new LinkedHashMap<String, Object>();
}
因为而不是HashMap
- LinkedHashMap
具有可预测的迭代顺序。
LinkedHashMap:Map接口的哈希表和链表实现,具有可预测的迭代顺序。
这是解决问题的最有效方法。
您还可以 fork 使用
中的自定义库