获取json数组中每个元素的键的数组

16
我希望动态解析我的Json数组,并想要获取jsonarray下每个元素的键的数组。我使用迭代器来实现这一点,但是获取的顺序与输出的JSON格式不一致。

我的JSON格式:

{
  "result": "Success",
  "AlertDetails": [
    {
      "ShipmentNumber": "SHP34",
      "Customer": "BEST",
      "DateCreated": "2012-08-29T04:59:18Z"
      "CustomerName": "BEST"
    },
    {
      "ShipmentNumber": "SHP22",
      "Customer": "BEST",
      "DateCreated": "2012-08-29T05:34:18Z"
      "CustomerName": "Jelly"
    }
  ]
}

这是我的代码:

    JSONArray array = jsonobject.getJSONArray("AlertDetails");

    JSONObject keyarray = array.getJSONObject(0);
    Iterator temp = keyarray.keys();
        while (temp.hasNext()) {
                    String curentkey = (String) temp.next();
                    KEYS.add(curentkey);

    }
Log.d("Parsing Json class", "  ---- KEYS---- " + KEYS);

我在logcat输出中得到的内容是:

 ---- KEYS---- [DateCreated,CustomerName, Customer, ShipmentNumber]

我想要的:

 ---- KEYS---- [ShipmentNumber, Customer, DateCreated,CustomerName]

@LazyNinja 不,这只是一个名字。 - Yog Guru
@LazyNinja 是的,它是一个ArrayList。你能帮我解决这个问题吗?如果你能给我一些建议就太好了。 - Bhavesh Patadiya
1
有没有人告诉过你,JSON对象不遵循任何特定的顺序...两个输出根据JSON格式是相等的...现在问题是为什么你想要以那种特定的格式呢? - MKJParekh
@MKJParekh:感谢您的支持。但是我想在屏幕上显示每个KEY名称作为列名,以相同的格式显示我从WS响应中获取的数据。这些KEYS事先不为我所知。 - Bhavesh Patadiya
然后在您的WS响应中添加一件事...一个JSON对象,其中键名为其索引ID 1,名称2日期3的值..等等...并根据此决定... - MKJParekh
或者您可以将您的WS从JSON转换为XML或SOAP。那也可以。 - MKJParekh
5个回答

12
JSONObject的文档(链接:http://developer.android.com/reference/org/json/JSONObject.html)为keys()函数提供了以下说明: public Iterator keys ()
自:API Level 1
返回此对象中的String名称的迭代器。返回的迭代器支持remove操作,该操作将从该对象中删除相应的映射关系。如果返回迭代器后修改了该对象,则迭代器的行为是未定义的。键的顺序是未定义的
因此,您可以获取这些键,但是它们的顺序是未定义的。如果您想要以任何特定顺序获得键,则可以使用任何排序算法。
编辑:
由于您不知道来自WS的KEYS的顺序,因此在接收到数据后,可以以有序的格式在屏幕上显示详细信息。构建arraylist KEYS之后,您可以按字母顺序进行排序,方法如下:
Collections.sort(KEYS);  

这将按照它的自然顺序(即字母顺序)对KEYS arraylist中的Strings进行排序。


1
谢谢您的支持。您能否建议我解决这个问题的任何算法,并且可以给我一个与我从WS响应中获取的KEYS顺序相同的Arraylist? - Bhavesh Patadiya

6

我刚刚知道了,当我按下 ctlr+space bar 时,其中明确写着 keys 的行为是未定义的,键的顺序没有被维护。

enter image description here

Arun George 正确地说,您必须使用任何排序方法来实现您的目标。

而对于排序,也许这个链接会对您有所帮助。


6

使用Google的GSON库。它有很多设置可以读取/创建/解析JSON数组和JSON对象。我没有测试过它来找到解决方案,但我认为它是一个非常简单且功能齐全的工具,可以解决这个问题。


4

使用不同的库来动态解析JSON。

下面是我基于Jackson JSON处理器编写的一段代码,它是我认为最好的JSON库。

public void test() throws IOException {
    String str = "{\n" +
            "  \"result\": \"Success\",\n" +
            "  \"AlertDetails\": [\n" +
            "    {\n" +
            "      \"ShipmentNumber\": \"SHP34\",\n" +
            "      \"Customer\": \"BEST\",\n" +
            "      \"DateCreated\": \"2012-08-29T04:59:18Z\",\n" +
            "      \"CustomerName\": \"BEST\"\n" +
            "    }\n" +
            "  ]\n" +
            "}";

    JsonFactory factory = new JsonFactory();
    JsonParser jsonParser = factory.createJsonParser(str);

    JsonToken jsonToken;
    SerializedString alertDetails = new SerializedString("AlertDetails");
    while (!jsonParser.nextFieldName(alertDetails)) { /* move to AlertDetails field */ }

    jsonParser.nextToken(); // skip [ start array
    jsonParser.nextToken(); // skip { start object
    // until } end object
    while ((jsonToken = jsonParser.nextToken()) != JsonToken.END_OBJECT) {
        if (jsonToken == JsonToken.FIELD_NAME) {
            System.out.println(jsonParser.getCurrentName());
        }
    }

}

它只是按照json中的顺序打印出字段名称:
ShipmentNumber
Customer
DateCreated
CustomerName

编辑

当然,你可以使用其他库,如gson等。但要记住,正如json.org上所写的那样:

对象是一个无序的名称/值对集合。

键的顺序取决于实现,并且可能在每个请求中有所不同。


3

还有一种方法names();

返回一个包含此对象中字符串名称的数组。

编辑:按未定义顺序返回名称。建议自行解析。


是的,你说得对。我也尝试过了,但使用key()方法仍然会出现相同的未定义键顺序问题。如果您有更多解决此问题的建议,将不胜感激。 - Bhavesh Patadiya
那我建议你自己解析它。 - Dominic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接