2014-01-25 70 views
1

我有一个复杂的JSON,下面我需要递归解析。递归的最终结果是Map>对象的类型,其中key是受众 - 名称值,内部映射是Text-key,Title-value。 这只是完整JSON的一部分。通过JSONObject递归解析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这个才意识到已经很晚该迭代发生在相反的顺序:(

我试图递归解析整体的结构,它扭转到我的利益,但为了即将失控:(:(主要是因为文本,标题,跟在第二个文本后面的片段,标题和2个观众名称。该部分的文本和标题被跳过,因此整个订单被盗用

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

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

为什么使用你需要递归解析它?这里没有“嵌入JSON”,所以它是一个相对简单的“对象”/地图(我可以看到没有数组/列表)。除了由数字键控的地图(有点傻 - 为什么不使用数组),不需要遍历键 - 可以简单地通过键提取每个值。 –

+0

递归是需要的,因为返回对象用于将值放入POJO中。这些值反过来用于以某种方式生成XML ..部分任务需求...我知道编号映射是愚蠢的..但是需要处理它们:(..加上需要文本,标题映射到观众..在XML中,根据受众名称,文本和标题放在不同的标签.. – HungryForKnowledge

+0

您可能需要递归处理解析的JSON,但不需要递归解析,也不需要使用异常处理程序 - 您可以“获取”对象并检查其类型以避免异常(并且,无论如何,您绝对不应该捕捉到“异常”特别是如果你只是假设它是一个'JSONException'并且“吞下”它,当它可能是别的东西的时候。) –

回答

0

找到了解决的ordering..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; 
} 
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"> 
    } 
} 
+0

它的递归..我通过keys迭代..如果它是一个独立的或单一的循环...我可以做与has ..但我怎么把它在这里 – HungryForKnowledge

+0

@HungryForKnowledge - 不需要遍历键。而且,因为你总是使用'getJSONObject',你会得到所有字符串值的异常。既然你知道TEXT总是一个字符串,那么对其执行'getJSONObject'就会很愚蠢,并且只要执行'getString'就会发生异常。 –

+0

和你如何计划处理递归,如果你继续做getString?整个观点是通过一个对象递归。当一个getObject抛出异常...意味着它是一个String ..这是当我做一个getString .. – HungryForKnowledge

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 
+0

你能详细解释一下吗? – Ares

+1

有一个JSONObject和JSONArray的树,这个算法遍历所有键和所有值并将它们打印出来 – sklimkovitch

+0

将其编辑到问题中,并解释它如何回答用户的问题 – Ares