XML转换后Java中JSON元素的反转顺序

时间:2014-09-25 08:55:10

标签: java json

我使用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?

8 个答案:

答案 0 :(得分:9)

所以我的问题。如何在保持顺序的情况下转换为JSON?

目前的官方JSONObject,这是不可能的。 API非常清楚:

  

JSONObject是名称/值对的无序集合。

,您的问题可能会有一个快速的解决方法。正如我在JSONObject source code中所调查的那样,您可以看到它在内部使用HashMap,并且您知道HashMap不会保留任何顺序。

public JSONObject() { this.map = new HashMap<String, Object>(); }

您有两种选择:

  1. 修改当前的JSONObject源代码,以便使用LinkedHashMap初始化地图。 LinkedHashMap是 Map接口的一个实现,具有可预测的迭代顺序

    public JSONObject() {
          this.map = new LinkedHashMap<String, Object>();
    }
    
  2. 创建自己的自定义类,扩展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)

  1. 您可以从http://www.json.org/java/下载源代码,并使用TreeMap而不是HashMap修改JSONObject.java。

  2. 您还可以覆盖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 使用

中的自定义库
  

https://github.com/SergeyShustikov/JSON-java