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

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

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

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

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

解決済

入れ子になったjsonをVB.NETでパースする方法をご教示ください

bananaman
bananaman

総合スコア7

JSON

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

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

1回答

0グッド

2クリップ

15634閲覧

投稿2018/04/06 12:27

VS2017環境のVB.NETで、以下のようなjsonをパースしようとしましたが、エラーで困っています。
以下のようなjsonなのですが、contentのmenusが配列構造になっており、このgradeとmarkの値を取得する方法がわかりません。

//////////// json ///////////////
{
"response": {
"id": "xxxxxx",
"content": {
"menus": [
{
"grade": "A",
"mark": "1"
},
{
"grade": "B",
"mark": "2"
},
{
"grade": "C",
"mark": "3"
},
{
"grade": "D",
"mark": "4"
}
]
}
}
}
/////////// jsonここまで ///////////

VS標準の以下を参照してデシリアライズしています。
[参照]
Imports System.Runtime.Serialization.Json
[デシリアライズクラス]
Public Function Deserialize(Of T)(ByVal json As String) As T
Dim result As T
Dim serializer As New DataContractJsonSerializer(GetType(T))

Using stream As New IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(json)) result = DirectCast(serializer.ReadObject(stream), T) End Using Return result

End Function

Public Class grade_select_Rootobject
Public Property response As Response
End Class

Public Class grade_select_Response
Public Property id As String
Public Property content As grade_select_Content
End Class

Public Class grade_select_Content
Public Property menus() As grade_select_Menu
End Class

Public Class grade_select_Menu
Public Property grade As String
Public Property mark As String
End Class

以下は実行部分とそのエラーです。
[jsonの読み込み]
Rootobject = Deserialize(Of grade_select_Rootobject)(json)

[menusの件数取得]
Dim count As Integer = Rootobject.response.content.menus.Count
→ 9が取得できます。

この後、取得した件数(9)でループをしながら、各gradeとmarkを取得できると考えていました。
Dim i As Integer
For i = 0 To count - 1
MsgBox(grade_select_Rootobject.response.content.menus(i).grade.ToString)
Next
ループ内のメッセージボックスで、gradeの値が1件ずつ表示されると想定していましたが、
エラーメッセージは、「公開メンバー'grade'は型'Object'にみつかりませんでした」です。

どなたかお知恵のある方、解決策あるいは小職がミスをしている箇所をご指摘いただけないでしょうか。
よろしくお願いいたします。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

coco_bauer

2018/04/07 01:38

質問に書かれている jsonのデータでは、menusは4要素の配列ですよね?  「件数(9)」という解釈は間違っていませんか?
dodox86

2018/04/07 03:14 編集

コードも未完成のように見えます。 プロパティのPublic Property response As Response は、Public Property response As grade_select_Response の間違いではありませんか? また、読みにくいのでコード貼り付けもマークダウンを利用しましょう。 https://teratail.com/help#about-markdown

回答1

0

ベストアンサー

一部補完して宣言の仕方など修正しましたが、おおむね元のご提示のコードでご要望のとおり動作しています。もとのコードに不備があったのではないでしょうか。再度確認してみてください。

(Visual Studio 2017 + .NET Framework 4.5 環境で確認)

UTF8 BOM有りのJsonファイルの内容(D:\data.json)

{ "response": { "id": "xxxxxx", "content": { "menus": [ { "grade": "A", "mark": "1" }, { "grade": "B", "mark": "2" }, { "grade": "C", "mark": "3" }, { "grade": "D", "mark": "4" } ] } } }

コードです。(WPF)

Imports System.Runtime.Serialization.Json Imports System.Text Class MainWindow Private Shared path As String = "D:\data.json" Public Function Deserialize(Of T)(ByVal json As String) As T Dim result As T Dim serializer As New DataContractJsonSerializer(GetType(T)) Using stream As New IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(json)) result = DirectCast(serializer.ReadObject(stream), T) End Using Return result End Function Private Sub Button1_Click(sender As Object, e As RoutedEventArgs) Handles Button1.Click Dim json As String = System.IO.File.ReadAllText(path, Encoding.UTF8) Using stream As New IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(json)) Dim root As grade_select_Rootobject root = Deserialize(Of grade_select_Rootobject)(json) Debug.Assert(root.response.content.menus IsNot Nothing) Dim count As Integer = root.response.content.menus.Count Trace.WriteLine("count = " + count.ToString()) For i As Integer = 0 To count - 1 Dim grade As String = root.response.content.menus(i).grade Dim mark As String = root.response.content.menus(i).mark Dim s As String = String.Format("{0}: grade={1}, mark={2}", i + 1, grade, mark) Trace.WriteLine(s) Next End Using End Sub End Class Public Class grade_select_Rootobject Public Property response As grade_select_Response End Class Public Class grade_select_Response Public Property id As String Public Property content As grade_select_Content End Class Public Class grade_select_Content ' Public Property menus() As grade_select_Menu Public Property menus As grade_select_Menu() End Class Public Class grade_select_Menu Public Property grade As String Public Property mark As String End Class

実行結果です。

count = 4 1: grade=A, mark=1 2: grade=B, mark=2 3: grade=C, mark=3 4: grade=D, mark=4

投稿2018/04/07 05:33

dodox86

総合スコア9146

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

bananaman

2018/04/07 17:27

ありがとうございました。コード不備が原因でした。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

JSON

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

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。