【问题标题】:Parse JSON for first instance of repeated data field in Java with org.JSON使用 org.JSON 为 Java 中重复数据字段的第一个实例解析 JSON
【发布时间】:2018-09-29 22:24:11
【问题描述】:

我正在尝试从以下 JSON 文件中解析“actualEPS​​”的第一个实例:

   {"symbol":"AAPL","earnings":[{"actualEPS":2.34,"consensusEPS":2.17,"estimatedEPS":2.17,"announceTime":"AMC","numberOfEstimates":10,"EPSSurpriseDollar":0.17,"EPSReportDate":"2018-07-31","fiscalPeriod":"Q3 2018","fiscalEndDate":"2018-06-30","yearAgo":1.67,"yearAgoChangePercent":0.40119760479041916,"estimatedChangePercent":0.29940119760479045,"symbolId":11},{"actualEPS":2.73,"consensusEPS":2.69,...}

这是目前的方法。我知道我正在从目标获取数据,因为我可以 Sysout 字符串“inputLine”并查看完整文件。从那时起我很难解析。我已经安装并导入了 org.JSON 库。

    public static void getData(String s) throws Exception {
    String urlBase = new String(theWebSiteImGettingDataFrom)
    URL targetURL = new URL(urlBase);
    URLConnection yc = targetURL.openConnection();
    BufferedReader in = new BufferedReader(
                            new InputStreamReader(
                            yc.getInputStream()));
    String inputLine;

    while ((inputLine = in.readLine()) != null) { 

        System.out.println(inputLine);
    } // end while

    in.close();

    JSONObject obj = new JSONObject(inputLine);
    double eps = obj.getJSONObject("earnings").getDouble("actualEPS");

    System.out.println("This is the first instance of EPS: " + eps);

} // end getData method

我在堆栈跟踪中收到空指针异常:

    at org.json.JSONTokener.<init>(JSONTokener.java:94)
at org.json.JSONObject.<init>(JSONObject.java:357)
at code.URLConnectionReader.getData(URLConnectionReader.java:39)

如何解析“actualEPS​​”第一个实例的数据并且只解析第一个实例?

编辑

    JSONObject obj = new JSONObject(inputLine);
    JSONArray earningsArray = obj.getJSONArray("earnings");
    JSONObject firstEPS = earningsArray.getJSONObject(0);
    double eps = firstEPS.getDouble("actualEPS");

    System.out.println("This is the first instance of EPS: " + eps);

【问题讨论】:

    标签: java json parsing org.json


    【解决方案1】:

    首先,由于我不知道您的 json 有多大,并且您只想解析 json 本身的特定部分,我建议您使用 JsonReader.class 而不是JsonObject.class

    短差:

    • JsonObject 将整个 json 解析到 RAM 中,需要小于 1 MB。
    • JsonReader 使用流式处理方法,可以让您更有效地处理大型 json。

    其次,如果你知道你总是只需要你的 json 的第一个实例,你可以在解析它之前简单地缩短你的 jsonString 本身(例如substring 等)。


    现在到你的代码:

    public static void getData(String s) 抛出异常 { String urlBase = new String(theWebSiteImGettingDataFrom); // 分号! URL targetURL = 新 URL(urlBase); URLConnection yc = targetURL.openConnection(); BufferedReader in = new BufferedReader( 新的 InputStreamReader( yc.getInputStream())); 字符串输入线;

    while ((inputLine = in.readLine()) != null) { 
    
        System.out.println(inputLine);
    } // end while
    
    in.close();
    
    System.out.println("My json: "+inputLine); //TODO: What is your output here?  
    
    JSONObject obj = new JSONObject(inputLine);
    double eps = obj.getJSONObject("earnings").getDouble("actualEPS");
    
    System.out.println("This is the first instance of EPS: " + eps);
    

    } // 结束 getData 方法

    请发表评论,因为我无法判断您是否从服务器获取 json。


    编辑: 您的错误在这一行:

    double eps = obj.getJSONObject("earnings").getDouble("actualEPS");
    

    简而言之应该是这样的:

    double eps = obj.getJSONArray("earnings").getJSONObject(0).getDouble("actualEPS");
    

    但是,为什么?您的属性收益返回一个 JSONArray(这意味着您有多个带有 indizes 的行)。因此,与其仅仅将“收益”请求为 JSONObject,不如将其用作 JSONArray,然后提取第一行 (= .getJSONObject(0))。提取第一行后,您实际上可以使用您的双值。

    我希望这有效:)


    第二次编辑: 改变它..

    while ((inputLine = in.readLine()) != null) {

    System.out.println(inputLine); } // end while
    

    到:

    while ((inputLine += in.readLine()) != null) {

    System.out.println(inputLine); } // end while
    

    您的 while 循环不断迭代 直到 .readLine() 返回 null。 由于 null 是最后一次迭代,因此您的变量中只有 null 。

    按照建议,您只需将 = 更改为 += 即可解决此问题。

    我希望我们现在明白了。 :)

    【讨论】:

    • 我使用 HTTP 请求从网页获取 JSON,这是您要问的吗?我对 JSON 完全陌生。这些文件通常小于 10kb,你还会推荐 JsonReader 吗?并非所有文件都会遇到我要解析的数据的多个实例,实际上它应该只有一个。通常,我会寻找解析出特定且唯一的数据,该数据将是 String 或 double。
    • 如果它们小于 10kb 那么 JSONObject 完全没问题!
    • 抱歉,我已经看到了实际错误!我编辑了我的帖子!
    • JSONArray 是一个很大的帮助,直到你指出它才发现区别。但是,根据您的建议,我仍然收到空指针异常。我在编辑中尝试了上面的代码,结果相同,NULL 指针异常。还有其他想法吗?
    • 我的第一个答案中建议的输出是什么? System.out.println("我的 json:"+inputLine); //TODO: 你的输出是什么?
    猜你喜欢
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多