2

私はJsonReaderAndroid のストリーミング JSON パーサーで遊んでいますが、パーサーが json 配列内のすべての項目を処理しないという問題に遭遇しました。最初の項目のみが返されます。

解析に使用するコードは次のとおりです。

private ArrayList<Result> readResultsArray(JsonReader reader) throws IOException {
    ArrayList<Result> results = new ArrayList<Result>();

    reader.beginObject();
    while (reader.hasNext()) {
        String name = reader.nextName();
        if (name.equals("results")){
            reader.beginArray();
            while (reader.hasNext()) {
                results.add(readResult(reader));
            }
            reader.endArray();
        } else {
            reader.skipValue();
        }
    }
    reader.endObject();

    return results;
}

readResult(reader)メソッドが問題なく配列内の最初のオブジェクトを解析して返すと確信しています。

しかし、リーダーは配列の 2 番目のオブジェクトを「無視」しているように見えました。

readResult(reader)メソッドは次のとおりです。

    private Result readResult(JsonReader reader) throws IOException {

        String from_user = null, 
                from_user_id_str = null, 
                from_user_name = null,
                text = null;
        Geo geo = null;
        URL profile_image_url = null;

        reader.beginObject();
        while (reader.hasNext()) {
            String name = reader.nextName();
            if (name.equals("from_user")){

                from_user = reader.nextString();
                Log.i(TAG, from_user);
            } else if (name.equals("from_user_id_str")) {

                from_user_id_str = reader.nextString();
                Log.i(TAG, from_user_id_str);
            } else if (name.equals("from_user_name")) {

                from_user_name = reader.nextString();
                Log.i(TAG, from_user_name);
            } else if (name.equals("geo")) {

                reader.beginObject();

                while(reader.hasNext()) {
//                      String s = reader.nextName();
                        if (name.equals("coordinates")) {
                            reader.beginArray();
                            double latitude = 0;
                            double longitude = 0;
                            while (reader.hasNext()) {
                                latitude = reader.nextDouble();
                                longitude = reader.nextDouble();
                                Log.i(TAG, latitude + ", " + longitude);
                            geo = new Geo(latitude, longitude);
                        }
                        reader.endArray();
                    } else {
                        reader.skipValue();
                    }
                }
                reader.endObject();

            } else if (name.equals("profile_image_url")) {

                profile_image_url = new URL(reader.nextString());

            } else if (name.equals("text")) {

                text = reader.nextString();
                Log.i(TAG, text);
            } else {

                reader.skipValue();

            }

        }
        reader.endObject();


        return new Result(from_user, from_user_id_str, from_user_name, text, geo, profile_image_url);
    }

}

解析しようとしたJSONは次のとおりです。

(これは Twitter の検索応答です。元の応答は以下のように表示されます。リンク)

{
  "completed_in": 0.067,
  "max_id": 320160565840457730,
  "max_id_str": "320160565840457730",
  "page": 1,
  "query": "%E5%90%83",
  "refresh_url": "?since_id=320160565840457730&q=%E5%90%83&geocode=51.483372%2C-3.190826%2C200mi",
  "results": [
    {
      "created_at": "Fri, 05 Apr 2013 13:06:41 +0000",
      "from_user": "missmanchu",
      "from_user_id": 359296258,
      "from_user_id_str": "359296258",
      "from_user_name": "miss manchu ",
      "geo": null,
      "location": "London, United Kingdom",
      "id": 320160565840457730,
      "id_str": "320160565840457730",
      "iso_language_code": "ja",
      "metadata": {
        "result_type": "recent"
      },
      "profile_image_url": "http://a0.twimg.com/profile_images/3470783234/6ae4049d90a052c7a9c7f86ec804e523_normal.jpeg",
      "profile_image_url_https": "https://si0.twimg.com/profile_images/3470783234/6ae4049d90a052c7a9c7f86ec804e523_normal.jpeg",
      "source": "&lt;a href=&quot;http://twitter.com/download/iphone&quot;&gt;Twitter for iPhone&lt;/a&gt;",
      "text": "RT @lougirlie: Delish Taiwanese-style bao by @missmanchu for lunch. 好吃! http://t.co/clRznskvqe"
    },
    {
      "created_at": "Fri, 05 Apr 2013 11:45:09 +0000",
      "from_user": "lougirlie",
      "from_user_id": 154974289,
      "from_user_id_str": "154974289",
      "from_user_name": "Louise Chow",
      "geo": {
        "coordinates": [
          51.5216788595,
          -0.1420583511
        ],
        "type": "Point"
      },
      "id": 320140044142772224,
      "id_str": "320140044142772224",
      "iso_language_code": "ja",
      "metadata": {
        "result_type": "recent"
      },
      "place": {
        "full_name": "Westminster",
        "id": "548c2b8e3921a85a",
        "type": "CITY"
      },
      "profile_image_url": "http://a0.twimg.com/profile_images/1750994903/photo_3__4__normal.JPG",
      "profile_image_url_https": "https://si0.twimg.com/profile_images/1750994903/photo_3__4__normal.JPG",
      "source": "&lt;a href=&quot;http://twitter.com&quot;&gt;Twitter for  iPhone&lt;/a&gt;",
      "text": "Delish Taiwanese-style bao by @missmanchu for lunch. 好吃! http://t.co/clRznskvqe"
    },
    {
      "created_at": "Fri, 05 Apr 2013 10:09:25 +0000",
      "from_user": "geleikai",
      "from_user_id": 351512769,
      "from_user_id_str": "351512769",
      "from_user_name": "geleikai",
      "geo": null,
      "location": "53.762824,-2.707418",
      "id": 320115951339200512,
      "id_str": "320115951339200512",
      "iso_language_code": "zh",
      "metadata": {
        "result_type": "recent"
      },
      "profile_image_url": "http://a0.twimg.com/profile_images/3110335584/545b94d39e1628d747428c73a8052bf8_normal.jpeg",
      "profile_image_url_https": "https://si0.twimg.com/profile_images/3110335584/545b94d39e1628d747428c73a8052bf8_normal.jpeg",
      "source": "&lt;a href=&quot;http://www.wechatapp.com&quot;&gt;WeChat App&lt;/a&gt;",
      "text": "吃过午饭,前往阿姆斯特丹 http://t.co/LbQ0Jh7Mfp"
    },
    {
      "created_at": "Thu, 04 Apr 2013 10:15:05 +0000",
      "from_user": "hpfly",
      "from_user_id": 60939059,
      "from_user_id_str": "60939059",
      "from_user_name": "0C哈根达斯",
      "geo": null,
      "location": "53.805042,-1.544011",
      "id": 319754991692824576,
      "id_str": "319754991692824576",
      "iso_language_code": "zh",
      "metadata": {
        "result_type": "recent"
      },
      "profile_image_url": "http://a0.twimg.com/profile_images/3251267049/c56ca4cb888736299548e5454a9d923b_normal.jpeg",
      "profile_image_url_https": "https://si0.twimg.com/profile_images/3251267049/c56ca4cb888736299548e5454a9d923b_normal.jpeg",
      "source": "&lt;a href=&quot;http://fanfou.com&quot;&gt;fanfou2.0&lt;/a&gt;",
      "text": "现在对谈恋爱一点欲望都没有,更多的欲望是告诉我,我内心希望独享一个人的时光。现在特别希望晚睡,而且是晚上一个人吃着宵夜,看着电视。#如果生活可以这么单纯就好了##当然这也是晚睡的牵强理由#"
    },
    {
      "created_at": "Wed, 03 Apr 2013 15:47:50 +0000",
      "from_user": "cushingliu",
      "from_user_id": 87816289,
      "from_user_id_str": "87816289",
      "from_user_name": "Cushing",
      "geo": {
        "coordinates": [
          0.0,
          0.0
        ],
        "type": "Point"
      },
      "id": 319476345325359104,
      "id_str": "319476345325359104",
      "iso_language_code": "zh",
      "metadata": {
        "result_type": "recent"
      },
      "place": {
        "full_name": "Batu Ampar",
        "id": "ddc693317ed3f226",
        "type": "CITY"
      },
      "profile_image_url": "http://a0.twimg.com/profile_images/3269471232/f89db3764b70bada908ab340a9fb9c85_normal.jpeg",
      "profile_image_url_https": "https://si0.twimg.com/profile_images/3269471232/f89db3764b70bada908ab340a9fb9c85_normal.jpeg",
      "source": "&lt;a href=&quot;http://tapbots.com/tweetbot&quot;&gt;Tweetbot for iOS&lt;/a&gt;",
      "text": "有妈妈做饭吃的感觉真好"
    }
  ],
  "results_per_page": 15,
  "since_id": 0,
  "since_id_str": "0"
}

私が興味を持っている唯一の部分は"results"、2 つのオブジェクトの配列である です。

Android Developers - JsonReaderの例とこの素晴らしいチュートリアルを詳しく調べた後、私のものは基本的に彼らのものと違いがないことがわかりました。

では、私のコードの何が問題なのですか? json配列を反復できないのはなぜですか?

アップデート

のコードを貼り付けましたreadResult(reader)

4

1 に答える 1

7

元のコードで例外を引き起こす null ジオタイプを考慮していません。peek()null をチェックするために使用します。これを処理するようにコードを変更すると、両方のオブジェクトが出力されます。

class MyReader
{
    public void readBegin(JsonReader reader)
    {
        try
        {
            reader.beginObject();
            while (reader.hasNext())
            {
                String name = reader.nextName();
                if (name.equals("results"))
                {
                    reader.beginArray();
                    while (reader.hasNext())
                    {
                        read(reader);
                    }
                    reader.endArray();
                }
                else
                {
                    reader.skipValue();
                }
            }
            reader.endObject();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void read(JsonReader reader) throws Exception
    {

        String from_user = null, from_user_id_str = null, from_user_name = null, text = null;
        URL profile_image_url = null;

        reader.beginObject();
        while (reader.hasNext())
        {
            String name = reader.nextName();
            if (name.equals("from_user"))
            {
                from_user = reader.nextString();
                System.out.println(from_user);
            }
            else if (name.equals("from_user_id_str"))
            {

                from_user_id_str = reader.nextString();
            }
            else if (name.equals("from_user_name"))
            {

                from_user_name = reader.nextString();
            }
            else if (name.equals("geo"))
            {
                if (reader.hasNext())
                {
                    JsonToken peek = reader.peek();
                    if (peek == JsonToken.NULL)
                    {
                        reader.skipValue();
                    }
                    else
                    {
                        reader.beginObject();
                        while (reader.hasNext())
                        {
                            // String s = reader.nextName();
                            if (name.equals("coordinates"))
                            {
                                reader.beginArray();
                                double latitude = 0;
                                double longitude = 0;
                                while (reader.hasNext())
                                {
                                    latitude = reader.nextDouble();
                                    longitude = reader.nextDouble();
                                }
                                reader.endArray();
                            }
                            else
                            {
                                reader.skipValue();
                            }
                        }
                        reader.endObject();
                    }
                }

            }
            else if (name.equals("profile_image_url"))
            {

                profile_image_url = new URL(reader.nextString());

            }
            else if (name.equals("text"))
            {

                text = reader.nextString();
            }
            else
            {
                reader.skipValue();
            }
        }
        reader.endObject();
    }
于 2013-04-08T13:17:33.413 に答える