質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

4919閲覧

JSONデータの配列から特定の要素を抽出したい

ehyai

総合スコア43

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2017/09/18 16:35

編集2017/09/18 16:41

###前提・実現したいこと
こちらのサイト①を参考にして、gooのPOSTAPIを利用して文章を形態素解析し、その結果の中から単語だけを抜き出したいと考えています。
具体的に言うと、上述のサイトに示されている、

{"request_id":"labs.goo.ne.jp\t..\t0", "word_list":[[ ["京都","名詞","キョウト"], ["は","連用助詞","ハ"], ["めちゃめちゃ","名詞","メチャメチャ"], ["楽し","形容詞語幹","タノシ"], ["い","形容詞接尾辞","イ"]]] }

が解析結果(JSONデータ)で、word_listは解析結果の本体が格納されたもので、その中の値にあたる配列の["京都","名詞","キョウト"]は、それぞれ単語の表記、形態素、読みを表しています。そして、このうち、word_listの中の表記を表す、「京都」「は」「めちゃめちゃ」「楽し」「い」を抜き出したいと考えています。
今回のシステムはAndroid Studio上で構築したもので、解析結果とは別に、word_listの中の表記も一緒にスマートフォン上に表示したいと思います。
その際に、Android上でJSONデータの表示を行う方法が書かれたこちらのサイト②のうち、パース方法4のやり方なら実現できるのではと思い、試してみました。
このパース方法4が解析を行うJSONデータは、

{ datas : [ { name : "名前1", age : "年齢1" }, { name : "名前2", age : "年齢2" }, { name : "名前3", age : "年齢3" } ] }

というものです。

###発生している問題・エラーメッセージ
しかし、サイト①の解析結果のword_listの表記、形態素、読みには、サイト②における"キー(名前)"、つまり「name」「age」にあたる部分が存在しないことが気がかりに感じました。
そこで、こちらのサイト③を調べて、
表記、形態素、読みの"キー(属性名)"は、それぞれForm、Pos、Readにあたるのではないかと思いました。
実際に書いたソースコードは、以下のようになりました。

try { JSONObject json = new JSONObject(JSONデータ); JSONArray datas = json.getJSONArray("word_list"); for (int i = 0; i < datas.length(); i++) { JSONObject data = datas.getJSONObject(i); //この次でエラーが起こり、catch e.printStackTraceへといってしまう //Form(表記)を取得 String form = data.getString("Form"); str += form; //strは実際に表示を行うための変数 } } catch (JSONException e) { e.printStackTrace(); } //ここまで str += JSONデータ; //ここでJSONデータを表示に追加する

しかし、デバッグを行うと、上記のJSONObject data = datas.getJSONObject(i);のところでエラーが発生し、catch (JSONException e) のところへと進んでしまいます。
エラーメッセージとして、

at 0 of type org.json.JSONArray cannto be converted to JSONObject

と書かれていました。
どのようにすれば解析結果のword_listのような、"キー(属性名)"が描かれていないJSONデータの取得を行うことができるか、そのアドバイスを教えていただきたいと思いますので、よろしくお願いします。
ちなみに、サイト④のパース方法1の方法で、word_listではなくrequest_idを取得しようと以下のコードでデバッグすると、「labs.goo.ne.jp\t..\t0」を正しく取得できました。

try { JSONObject json = new JSONObject(JSONデータ); String data1 = json.getString("request_id"); str += data1; //ここで表示に追加する } catch (JSONException e) { e.printStackTrace(); } //ここまで str += JSONデータ; //ここでJSONデータを表示に追加する

###該当のソースコード
MainActivity.java

package com.example.ehyai.(プロジェクト名); import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.text.SpannableStringBuilder; import android.widget.TextView; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.URL; import java.net.URLConnection; public class MainActivity extends AppCompatActivity { TextView textView; final String GOO_URL = "https://labs.goo.ne.jp/api/morph"; String ID = "(自分で取得したアプリケーションID)"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textView); } public void onClickButton1(View view) { EditText edit = (EditText)findViewById(R.id.editText); SpannableStringBuilder sp = (SpannableStringBuilder)edit.getText(); String str = sp.toString();//editTextの文章を入れる変数 URL url = null; try{ url = new URL(GOO_URL); URLConnection connection =url.openConnection(); connection.setDoOutput(true); //ヘッダ connection.setRequestProperty("Content-Type", "application/json"); OutputStream os = connection.getOutputStream(); String postStr = "{\"app_id\": \"" + ID + "\",\"sentence\": \"" + str + "\"}"; PrintStream ps = new PrintStream(os); ps.print(postStr); //データをPOSTする ps.close(); InputStream is = connection.getInputStream(); //結果を取得 BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String s; while ((s = reader.readLine()) != null) { try { JSONObject json = new JSONObject(s); JSONArray datas = json.getJSONArray("word_list"); for (int i = 0; i < datas.length(); i++) { JSONObject data = datas.getJSONObject(i); //この次でエラーが起こり、catch e.printStackTraceへといってしまう //Form(表記)を取得 String form = data.getString("Form"); textResult += form; } } catch (JSONException e) { e.printStackTrace(); } //ここまで textResult += s; //ここでJSONデータを表示に追加する } reader.close(); } catch (IOException e) { e.printStackTrace(); } textView.setText(textResult); //textViewに表示 } }

activity_main.xml

?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context="com.example.(プロジェクト名)" xmlns:android="http://schemas.android.com/apk/res/android"> <EditText android:id="@+id/editText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:ems="10" android:inputType="text|textMultiLine" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/editText" android:layout_toEndOf="@+id/button" android:onClick="onClickButton1" android:text="形態素解析" /> <ScrollView android:layout_width="368dp" android:layout_height="388dp" android:layout_below="@+id/button" tools:layout_editor_absoluteX="8dp" tools:layout_editor_absoluteY="115dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> </ScrollView> </RelativeLayout>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

JSONでは、{}で囲むとオブジェクト、[]で囲むと配列をそれぞれ表します。
つまり解析結果のJSONは下記のような構造になっています。
1-オブジェクトの中にrequest_idとword_listがあります。
2-request_idは文字列を値として持ちます。
3-word_listは配列(以降、A配列)を値として持ちます。
4-A配列はさらに配列(以降、B配列)を値として持ちます。
5-B配列は文字列の配列を値として持ちます。

ということで、1はJSONObject、3・4・5はJSONArrayとして扱わなければなりません。

投稿2017/09/18 17:50

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ehyai

2017/09/19 13:43

回答してくださってありがとうございます。 yonaさんのおかげでword_listの中の表記を表す要素を取得することができました。 具体的には以下の方法で達成できました。 try { JSONObject json = new JSONObject(s); JSONArray datas = json.getJSONArray("word_list"); //word_listの持つ配列、A配列 for (int i = 0; i < datas.length(); i++) { JSONArray datas2 = datas.getJSONArray(i); //int iの持つ配列、B配列 for (int u = 0; u < datas2.length(); u++) { JSONArray datas3 = datas2.getJSONArray(u); //int uの持つ文字列の配列 String form = datas3.getString(0); textResult += form; } } } 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問