2016-11-06 2 views
0

JSONデータを解析するためにJsonReaderを使用しています。これは、類似の構造の要素の大きな配列です。JsonReader - 配列を読み取るとスローされる名前は期待されていましたがNULLでした

[ 
    { 
     "type":"duel", 
     "discipline":"leagueoflegends", 
     "tournament_id":"57ee13fe140ba0cd2a8b4593", 
     "opponents":[ 
     { 
      "participant":null, 
      "forfeit":false, 
      "number":1, 
      "result":1, 
      "score":3 
     }, 
     { 
      "participant":null, 
      "forfeit":false, 
      "number":2, 
      "result":3, 
      "score":2 
     } 
     ], 
     "id":"58078b2770cb49c45b8b45bf", 
     "status":"completed", 
     "number":1, 
     "stage_number":1, 
     "group_number":1, 
     "round_number":1, 
     "date":"2016-10-01T05:00:00+0300", 
     "timezone":"Europe/Helsinki", 
     "match_format":null 
    }, 
    ... 
] 

この配列には何百もの類似の要素があります。私だけの各要素からいくつかのデータを必要と私はthisのようなコードを書いた:)

public List<Match> readJsonStream(InputStream in) throws IOException { 
    JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8")); 
    try { 
     return readMatchesArray(reader); 
    } finally { 
     reader.close(); 
    } 
} 

public List<Match> readMatchesArray(JsonReader reader) throws IOException { 
    List<Match> matches = new ArrayList<>(); 

    reader.beginArray(); 
    while (reader.hasNext()) { 
     matches.add(readMatch(reader)); 
    } 
    reader.endArray(); 
    return matches; 
} 

public Match readMatch(JsonReader reader) throws IOException { 
    String status = null, date = null, time = null; 
    Match.Bracket bracket = null; 
    int id = -1, round = -1; 
    Match.Team team1 = null, team2 = null; 

    reader.beginObject(); 
    while (reader.hasNext()) { 
     String name = reader.nextName(); 
     switch (name) { 
      case "number": 
       id = reader.nextInt(); 
       break; 
      case "status": 
       status = reader.nextString().toUpperCase(); 
       break; 
      case "group_number": 
       if (reader.nextInt() == 1) { 
        bracket = WINNERS; 
       } else if (reader.nextInt() == 2) { 
        bracket = LOSERS; 
       } 
       break; 
      case "round_number": 
       round = reader.nextInt(); 
       break; 
      case "date": 
       try { 
        String tempDateRaw = reader.nextString(); 
        String[] tempDate = tempDateRaw.split("T"); 
        String[] tempTime = tempDate[1].split(":"); 

        date = tempDate[0]; 
        time = tempTime[0] + ":" + tempTime[1]; 
       } catch (IllegalStateException e) { 
        date = null; 
        time = null; 
       } 
       break; 
      case "opponents": 
       int counter = 0; 
       reader.beginArray(); 
       while (reader.hasNext()) { 
        if (counter == 0) { 
         team1 = readTeam(reader); 
        } else { 
         team2 = readTeam(reader); 
        } 
        counter++; 
       } 
       reader.endArray(); 
       break; 
      default: 
       reader.skipValue(); 
       break; 
     } 
    } 
    reader.endObject(); 
    return new Match(team1, team2, id, round, bracket, status, date, time); 
} 


public Match.Team readTeam(JsonReader reader) throws IOException { 
    String teamName = null; 
    int score = -1; 
    boolean winner = false; 

    reader.beginObject(); 
    while (reader.hasNext()) { 
      String name = reader.nextName(); //this is where the error occurs 
      switch (name) { 
       case "participant": 
        if(reader.peek() != JsonToken.NULL) { 
         teamName = reader.nextString(); 
        } 
        else { 
         teamName = null; 
        } 
        break; 
       case "score": 
        if(reader.peek() != JsonToken.NULL) { 
         score = reader.nextInt(); 
        } 
        else { 
         score = -1; 
        } 
        break; 
       case "result": 
        if(reader.peek() != JsonToken.NULL) { 
         winner = reader.nextInt() == 1; 
        } 
        else { 
         winner = false; 
        } 
        break; 
       default: 
        reader.skipValue(); 
        break; 
      } 
    } 
    reader.endObject(); 

    return new Match.Team(teamName, score, winner); 
} 

私は相手の配列を解析しようとしているときしかし、私は(readTeamでエラーが発生している予想される名前が、NULLでしたと私は非常になぜこれが起こって混乱している。

最初に私はpeek()について知らなかったので、私はtry/catchを使ったreadMatch()メソッドでそれを変更しなければなりませんでしたが、問題とは関係ありません。私はこの特定のエラーについては何も見つけられませんでした。他の類似したエラー(期待される名前はstring/int/whatever)に関してかなりの話題がありますが、ここではうまくいかない理由を見つけることができません。それを修正する方法はありますか?

+0

'JSON'を解析するのに' GSON'を使用しない理由はありますか? –

+0

まあ、実際にはありません。私はまだJavaの初心者であり、Androidで完全なnewbですが、これがJSONの解析に関する最初のことでした。以前は、単にStringBuilderを使用してgetJSONObject()を使用しましたが、ファイルが非常に大きいのでメモリが不足していました。私はGSONを試すことができると思いますが、まず第一に、時間がかかりすぎず、第二に、私の問題は簡単に解決できると確信しています。私は原因を見つけることができません。 – tuptus

+0

時間を見つけたら 'GSON'を見てください。がんばろう。 –

答えて

0

申し訳ありませんが、解決策が見つかりました。思っていたとおり、予想よりも簡単でした。

if(reader.peek() != JsonToken.NULL) { 
    teamName = reader.nextString(); 
} 
else { 
    teamName = null; 
} 

いわゆる「リーダーカーソル」動かないので、それは基本的に(この場合は)TEAMNAMEの値に引っかかっています:だから基本的に私はこのように、null値をチェックしていたとき。したがって、最も簡単な解決策は、reader.skipValue();をブロックelseに入れることです。私はcase "group_number"の私のコードに別のバグも見つけましたが、実際には上記の "カーソル"を2回動かしていますが、解決策は明らかです。うまくいけばそれは誰かのために役立つでしょう。

関連する問題