2014-09-25 154 views
9

我使用JSON in Java將XML轉換爲JSON。我有這個實現反轉所有子元素的問題。XML轉換後Java中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); 

如何改造到JSON與保持元素的順序(如在XML中)?

+4

我的建議是不要擔心。沒有在XML或JSON元素中定義的隱含順序。 – mikea 2014-09-25 08:57:45

+3

不,在XML中元素的順序很重要 - 任何具有一系列元素(在XML模式中指定)的元素都在檢查元素的順序。所以這很重要......(也許不是用JSON,但至少在XML中是這樣)。 – FiveO 2014-10-15 12:06:01

+0

未定義JSON「對象」中元素的順序。即使你以某種方式得到你想要的訂單,但不能保證在處理JSON時保持該順序。 – 2014-10-15 12:12:56

回答

8

所以我的問題。如何在保持順序的情況下轉換爲JSON?

與當前官方JSONObject,這是不可能的。該API非常明確:

JSONObject是名稱/值對的無序集合。

,有可能是你的問題的快速解決方法。從我在JSONObject source code中調查的內容可以看出,它在內部使用了一個HashMap,並且您知道HashMap不保留任何順序。

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

你有2種選擇:

  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>(); 
        } 
    } 
    
+0

你看不到'地圖'字段,因爲是**私人**。只有**保護**或**公共**修飾者將被放置在這裏。 – 2014-10-15 12:58:34

+1

閱讀'map'聲明旁邊的註釋。我說過你**必須做的**,以便應用替代否2. – Daniel 2014-10-15 12:59:49

+0

Yeap,現在是正確的。 – 2014-10-15 13:02:03

-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接口的哈希表和鏈表實現,具有可預測的迭代順序。

所以是解決您的問題的最有效的方法。

,你也可以使用自定義庫從

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

+0

有什麼意義? – 2014-10-15 15:30:51

0

JSON對象沒有特定的順序。您當然可以更改序列化實現來保留訂單,但不能保證它在反序列化之後也保留。事實上,大多數JSON庫甚至沒有API來檢測原始JSON文本以何種順序被解析。使用對象時,您不應該關心排序。

如果您確實關心訂單,請使用JSON數組。

{"Person":[{"Child1":"a"},{"Child2":"b"}]} 
+1

看起來有人低估了所有的答案,但我真的很想知道對方倒下的原因。在JSON規範中不可能有一個有序的對象。數組是唯一有序的數據結構。如果你必須實現你自己的序列化器和解析器來完成自己的編組,你不再使用標準的JSON。唯一的其他選擇是將訂單移動到應用程序級別,例如使用可排序的鍵或添加其他屬性進行排序。 – Kapep 2014-10-17 09:30:24

0

JSONObject API不擔保元素責令 一個很好的解決這個問題,可以使用JSONArray,在JSONArray你插入的元素的順序保存。

因此,在你的情況下,你會爲​​每個人有一系列的「chides」。 您可能需要更改XML文件或手動將XML解析爲您的格式的json(JSONArray而不是您現在使用的)

0

如果您非常想要獲取輸出的順序,想要它,你總是可以嘗試覆蓋方法

toString() 
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"}} 

Concl usion

兒童訂單保留。當然,這個想法可以改進,它只是一個關於可以做什麼的POC,修改解析器。

0
  1. 您可以從http://www.json.org/java/下載源代碼,並使用樹形圖來代替HashMap的修改JSONObject.java。

  2. 您也可以在JSONObject中覆蓋方法。java

    public Iterator<String> keys() { 
        return this.keySet().iterator(); 
    } 
    

    確保Iterator是排序後的鍵之一。

0

如果你會使用Jackson的JSON序列化/反序列化,你可以簡單地把一個 @JsonPropertyOrder()註釋在類的頂部。

@JsonPropertyOrder({"Child1", "Child2"}) 
public class Person { 

    @JsonProperty("Child1") 
    public String child1; 

    @JsonProperty("Child2") 
    public String child2; 
} 
+0

我沒有java類表示。輸入XML結構必須是動態的並且可以更改。 – FiveO 2014-10-22 08:14:49