通过JSONObject递归解析JSON以获取特定键的值

时间:2014-01-25 18:31:36

标签: java json

我有一个复杂的JSON,我需要递归解析。递归的最终结果是Map>对象的类型,其中键是观众 - 名称值,内部地图是文本键,标题值。 这只是完整JSON的一部分。

"sections": {
  "1": {
    "1": {
      "1": {
        "title": "xxx",
        "text": "xxx",
        "tags": {
          "audience": {
            "1": {
              "name": "xxx",
              "title": "xxx",
              "id": "xxx"
            }
          },
          "styleHint": {
            "1": {
              "name": "xxx",
              "title": "xxx",
              "id": "xxx"
            }
          }
        }
      },
      "title": "xxx",
      "text": "xxx",
      "tags": {
        "audience": {
          "1": {
            "name": "xxx",
            "title": "xxx",
            "id": "xxx"
          }
        },
        "styleHint": {
          "1": {
            "name": "xxx",
            "title": "xxx",
            "id": "xxx"
          }
        }
      }
    },
    "2": {
      "title": "xxx",
      "text": "xxx",
      "tags": {
        "audience": {
          "1": {
            "name": "xxx",
            "title": "xxx",
            "id": "xxx"
          }
        },
        "styleHint": {
          "1": {
            "name": "xxx",
            "title": "xxx",
            "id": "xxx"
          }
        }
      }
    },
    "title": "xxx",
    "text": "xxx",
    "tags": {
      "audience": {
        "1": {
          "name": "xxx",
          "title": "xxx",
          "id": "xxx"
        },
        "2": {
          "name": "xxx",
          "title": "xxx",
          "id": "xxx"
        }
      },
      "styleHint": {
        "1": {
          "name": "xxx",
          "title": "xxx",
          "id": "xxx"
        }
      }
    }
  },
  "2": {
    "title": "xxx",
    "text": "xxx",
    "tags": {
      "audience": {
        "1": {
          "name": "xxx",
          "title": "xxx",
          "id": "xxx"
        }
      },
      "styleHint": {
        "1": {
          "name": "xxx",
          "title": "xxx",
          "id": "xxx"
        }
      }
    },
    "anchor":"xxx"

  },
  "3": {
    "1": {
      "title": "xxx",
      "text": "xxx",
      "tags": {
        "audience": {
          "tag": {
            "name": "xxx",
            "title": "xxx",
            "id": "xxx"
          }
        },
        "styleHint": {
          "tag": {
            "name": "xxx",
            "title": "xxx",
            "id": "xxx"
          }
        }
      }
    },
    "title": "xxx",
    "text": "xxx",
    "tags": {
      "audience": {
        "1": {
          "name": "xxx",
          "title": "xxx",
          "id": "xxxx"
        }
      },
      "styleHint": {
        "1": {
          "name": "xx",
          "title": "xxx",
          "id": "xxxx"
        }
      }
    }
  }  
}

我之前使用JSONObject只是为了很晚才意识到迭代以相反的顺序发生:(

我尝试递归地解析整个结构并将其反转为我的利益。 BUt命令是乱七八糟:( :(主要是因为文本,标题,片段跟随第二个文本,标题,并有2个受众名称。该部分的文本和标题被跳过,因为整个订单被妥协< / p>

请帮忙!!我目前的实施如下

private Map<String, Map<String, String>> parseTextAndTitle(JSONObject json,
        Map<String, Map<String, String>> ttMap, String article,
        List<String> usrGrp) throws JSONException {
    logger.info("Entering method..");
    String userGroup = null;
    Map<String, String> titleAndText = new LinkedHashMap<String, String>();
    Map<String, String> currMap = new LinkedHashMap<String, String>();
    Map<String, String> tempMap = new LinkedHashMap<String, String>();  

    Iterator<String> keys = json.sortedKeys();

    while (keys.hasNext()) {
        String key = keys.next();
        JSONObject value = null;String firstKey = null;
        String text = null;String title = null;
        int length = 0;
        try {
            value = json.getJSONObject(key);
            if (key.equalsIgnoreCase(STYLEHINT) || key.equalsIgnoreCase(ANCHOR)
                    || key.equalsIgnoreCase(INLINE)) {
                continue;
            }
            if (key.equals(TEXT)) {
                text = json.getString(key);
                text = removeHtmlTag(text);
                logger.debug("TEXT RETRIEVED:" + text);
                if(text != null) {
                    titleAndText.put(text, "");
                }
                else
                    logger.debug("Text not retrieved!!");
            }
            if (key.equals(TITLE)) {
                title = json.getString(TITLE);
                title = appendNewline(title);
                logger.debug("TITLE RETRIEVED:" + title);
                if (title != null) {
                    for (Map.Entry<String, String> iter : titleAndText
                            .entrySet())
                        firstKey = iter.getKey();
                    if(firstKey != null) {
                        titleAndText.put(firstKey, title);
                    }
                    else
                        logger.debug("NO key present in textAndTitle Map!!");
                }
            }
            if (key.equals(AUDIENCE_TAG)) {
                try {
                    length = value.length();
                    for (int i = 0; i < length; i++) {
                        userGroup = (String) value.getJSONObject(
                                String.valueOf(i + 1)).get(NAME);
                        logger.debug("USERGROUP RETRIEVED:" + userGroup);
                        usrGrp.add(userGroup);
                    }

                } catch (Exception e) {
                    userGroup = (String) value.getJSONObject(TAG).get(NAME);
                    logger.debug("USERGROUP RETRIEVED:" + userGroup);
                    usrGrp.add(userGroup);
                }
            }
            else{
                parseTextAndTitle(value, ttMap, article, usrGrp);
            }
        } catch (Exception e) {
            logger.debug("value not a JSON Object..rather an element");
            // Extract the text values
            if (key.equals(TEXT)) {
                text = json.getString(key);
                text = removeHtmlTag(text);
                logger.debug("TEXT RETRIEVED:" + text);
                if(text != null) {
                    titleAndText.put(text, "");
                }
                else
                    logger.debug("Text not retrieved!!");
            }
            if (key.equals(TITLE)) {
                title = json.getString(TITLE);
                title = appendNewline(title);
                logger.debug("TITLE RETRIEVED:" + title);
                if (title != null) {
                    for (Map.Entry<String, String> iter : titleAndText
                            .entrySet())
                        firstKey = iter.getKey();
                    if(firstKey != null) {
                        titleAndText.put(firstKey, title);
                    }
                    else
                        logger.debug("NO key present in textAndTitle Map!!");
                }
            }
        }
        if (!(usrGrp.isEmpty()) && !(titleAndText.isEmpty())
                && title != null) {
            if(usrGrp.size() > 1)
            {
                for(int i=0;i<usrGrp.size();i++)
                {
                    //If user group already present, extract current text,title map
                    //If not put usergroup as key, text,title map as value
                    if (ttMap.containsKey(usrGrp.get(i))) {
                        currMap = ttMap.get(usrGrp.get(i));
                        if (currMap.isEmpty()) {
                            ttMap.put(usrGrp.get(i), titleAndText);

                        } else {
                            currMap = ttMap.get(usrGrp.get(i));
                            for (Map.Entry<String, String> entry : currMap
                                    .entrySet()) {
                                tempMap.put(entry.getKey(),
                                        (String) entry.getValue());
                            }
                            for (Map.Entry<String, String> ttEntry : titleAndText
                                    .entrySet()) {
                                tempMap.put(ttEntry.getKey(),
                                        (String) ttEntry.getValue());
                            }
                            ttMap.put(usrGrp.get(i),tempMap);
                            //                          titleAndText = new LinkedHashMap<String, String>();
                            tempMap = new LinkedHashMap<String, String>();
                        }
                    }                       
                    else {
                        ttMap.put(usrGrp.get(i), titleAndText);
                    }
                }
                titleAndText.clear();

            }
            else
            {
                if (ttMap.isEmpty())
                {
                    tempMap = titleAndText;
                    ttMap.put(usrGrp.get(0), tempMap);
                }
                else {
                    currMap = ttMap.get(usrGrp.get(0));
                    if (currMap.isEmpty()) {
                        ttMap.put(usrGrp.get(0), titleAndText);
                    }else {
                        currMap = ttMap.get(usrGrp.get(0));
                        for (Map.Entry<String, String> entry : currMap
                                .entrySet()) {
                            tempMap.put(entry.getKey(),
                                    (String) entry.getValue());
                        }
                        for (Map.Entry<String, String> ttEntry : titleAndText
                                .entrySet()) {
                            tempMap.put(ttEntry.getKey(),
                                    (String) ttEntry.getValue());
                        }
                        ttMap.put(usrGrp.get(0),tempMap);
                        titleAndText.clear();

                    }
                }

            }
            usrGrp.clear();


        }

    }

    logger.info("Exiting method..");
    return ttMap;
}

4 个答案:

答案 0 :(得分:1)

package Test.json;

import java.util.Iterator;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class App {
    public static void main(String[] args) {
        String str = "{\"a\":\"1\", \"b\":\"2\", \"c\":[{\"d\":\"4\"},{\"e\":\"5\"},{\"f\":[{\"g\":\"6\"},{\"h\":\"7\"}]}], \"i\":8}";
        try {
            loopThroughJson(new JSONObject(str));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public static void loopThroughJson(Object input) throws JSONException {
        if (input instanceof JSONObject) {
            Iterator<?> keys = ((JSONObject) input).keys();
            while (keys.hasNext()) {
                String key = (String) keys.next();
                if (!(((JSONObject) input).get(key) instanceof JSONArray))
                    System.out.println(key + "=" + ((JSONObject) input).get(key));
                else
                    loopThroughJson(new JSONArray(((JSONObject) input).get(key).toString()));
            }
        }
        if (input instanceof JSONArray) {
            for (int i = 0; i < ((JSONArray) input).length(); i++) {
                JSONObject a = ((JSONArray) input).getJSONObject(i);
                Object key = a.keys().next().toString();
                if (!(a.opt(key.toString()) instanceof JSONArray))
                    System.out.println(key + "=" + a.opt(key.toString()));
                else
                    loopThroughJson(a.opt(key.toString()));
            }
        }

    }
}



Output: 
a=1
b=2
d=4
e=5
g=6
h=7
i=8

答案 1 :(得分:1)

修改后的@sklimkovitch代码以使其在某些复杂的Json结构中工作...

public void loopThroughJson(Object input) throws JSONException {

    if (input instanceof JSONObject) {

        Iterator<?> keys = ((JSONObject) input).keys();

        while (keys.hasNext()) {

            String key = (String) keys.next();

            if (!(((JSONObject) input).get(key) instanceof JSONArray))
                if (((JSONObject) input).get(key) instanceof JSONObject) {
                    loopThroughJson(((JSONObject) input).get(key));
                } else
                    System.out.println(key + "=" + ((JSONObject) input).get(key));
            else
                loopThroughJson(new JSONArray(((JSONObject) input).get(key).toString()));
        }
    }

    if (input instanceof JSONArray) {
        for (int i = 0; i < ((JSONArray) input).length(); i++) {
            JSONObject a = ((JSONArray) input).getJSONObject(i);
            loopThroughJson(a);
        }
    }

}

答案 2 :(得分:0)

而不是

while (keys.hasNext()) {
    <blah blah>
        if (key.equalsIgnoreCase(STYLEHINT) || key.equalsIgnoreCase(ANCHOR)
                || key.equalsIgnoreCase(INLINE)) {
            continue;
        }
        if (key.equals(TEXT)) {
            <blah blah>
        }
        if (key.equals(TITLE)) {
        ....

可以简单地编码:

text = json.getString(TEXT);
<deal with text>
title = json.getString(TITLE);
<etc>

如果某些键值可能不存在,只需在获取它们之前使用has测试它们的缺失。

由于STYLEHINT,ANCHOR和INLINE被忽略,因此无法获取它们。

要处理JSON的棘手布局,请执行以下操作:

if (json.has("title")) {
    <extract title/text/tags/stylehint as described above>
}
else {
    Iterator<String> keys = json.sortedKeys();
    while (keys.hasNext()) {
        // Note that "key" must be "1", "2", "3"...
        String key = keys.next();
        value = json.getJSONObject(key);
        <recursively call method using "value">
    }
}

答案 3 :(得分:0)

找到了ordered..ditched JSONObject API的解决方案,并改为使用gson JsonObject

private Map<String, List<String>> parseJsonSection(
        Map<String, List<String>> retTextMap, JsonObject jsonObject,
        String lastKey, StringBuffer tt, List<String> ttext)
                throws ParseException, JSONException {

    for (Entry<String, JsonElement> entry : jsonObject.entrySet()) {
        String key = entry.getKey();
        Object value = entry.getValue();
        logger.debug("Key:" + key + "\n" + value.toString());

        if (key.equalsIgnoreCase(STYLEHINT) || key.equalsIgnoreCase(INLINE)
                || key.equalsIgnoreCase(ANCHOR))
            continue;
        if (key.equalsIgnoreCase(TEXT)) {
            tt.append(value.toString());
            ttext.add(tt.toString());
        }
        if (key.equalsIgnoreCase(TITLE) && tt.length() == 0) {
            tt = new StringBuffer();
            tt.append(value.toString() + "-");
        }
        if (key.equalsIgnoreCase(NAME)) {
            logger.debug("Value of usergrp:" + value.toString());
            String usrGrp = value.toString();
            if (retTextMap.isEmpty()) {
                if (tt.toString() != null) {
                    List<String> temp = new ArrayList<String>();
                    temp = ttext;
                    retTextMap.put(usrGrp, temp);
                }
                return retTextMap;
            } else if (retTextMap.get(usrGrp) != null) {
                List<String> temp = retTextMap.get(value.toString());
                if (!temp.contains(tt.toString()))
                    temp.add(tt.toString());
                retTextMap.put(usrGrp, temp);
            } else if (retTextMap.get(usrGrp) == null) {
                if (tt != null) {
                    List<String> temp = new ArrayList<String>();
                    temp.add(tt.toString());
                    retTextMap.put(usrGrp, temp);
                    return retTextMap;
                }
            }
        }
        if (value instanceof JsonObject) {
            parseJsonSection(retTextMap, (JsonObject) value, key, tt, ttext);
        }
    }
    return retTextMap;
}