JSON.NETのJTokenを使ってJSONの中身を一つずつ参照しながら全項目を取得する


JSON形式のファイルを読み込んで、KeyとValueの値を全て取得するサンプルを作成しました。

ファイルから読み込んだJSON文字列をJSON.NETを使ってデシリアライズして、再起呼び出しによりJTokenの階層を辿りながら、JSONの中身を全て取得していきます。
Imports System.IO
Imports System.Text.Encoding
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq

Module Module1
    ''ログ出力用
    Dim writer As StreamWriter
    ''JProperty名出力用変数
    Dim jName As String = String.Empty

    Sub Main()
        ''JSON読み込み用
        Dim jText As String = String.Empty
        ''ファイルからJSONを読み込む
        Using reader As New StreamReader("test.json", GetEncoding("shift_jis"))
            jText = reader.ReadToEnd
        End Using

        ''文字列をJSONにデシリアライズ
        Dim jObj As Object = JsonConvert.DeserializeObject(jText)

        Try
            writer = New StreamWriter("log.txt", False, GetEncoding("shift_jis"))
            ''JSON分解関数を実行
            Call getJChildren(jObj.Children)

        Catch ex As Exception
            writer.WriteLine(ex.Message)
        Finally
            writer.Close()
            writer.Dispose()
        End Try

    End Sub

    Sub getJChildren(ByVal jTokens As JEnumerable(Of JToken))

        For Each jT As JToken In jTokens
            ''TypeがObjectではない場合
            If jT.Type <> JTokenType.Object Then
                ''TypeがPropertyの場合
                If jT.Type = JTokenType.Property Then
                    ''JProperty型に変更
                    Dim jP As JProperty = jT
                    ''Nameを取り出す
                    jName = jP.Name
                    writer.WriteLine("Property Name = " & jP.Name)

                    ''TypeがArrayの場合
                ElseIf jT.Type = JTokenType.Array Then
                    writer.WriteLine("Array Start >>>")
                    ''配列を一つずつ取り出して自分自身を再起呼び出し
                    For Each jArr As JToken In jT.ToArray
                        Call getJChildren(jArr.Children)
                    Next
                    writer.WriteLine("<<< Array End")
                    Exit Sub
                Else
                    ''JTokenの値を出力
                    writer.WriteLine(jName & " Value = " & jT.ToString)
                End If
            End If
            ''自分自身を再起呼び出し
            Call getJChildren(jT.Children)
        Next
    End Sub
End Module

Jtoken型の「Type」で判断して、JTokenTypeが「Property」の場合({"ユーザーID": "USER01"}など)はNameプロパティを取得します。
JTokenTypeが「Array」の場合([{"年月日": "20151005","データ": "ABCDEFG"},{"年月日": "20151005","データ": "ABCDEFG"}]など)は配列をループで回して一つずつ再起呼び出しで配列の中身を参照しています。
PropertyでもArrayでもない場合はJvalue型だと判断して、ToStringで値を取得します。

例えば、以下のようなJSONを読み込むと、

{
  "ユーザーID": "USER01",
  "データ": {
    "ヘッダ": {"ID": "A0001","パスワード": "xxxx"},
    "パラメータ": {
      "共通部": {
        "区分": "TEST",
        "プログラムID": "PP01",
        "機能コード": "01",
        "受付日": "20171221",
        "キー値": {"Key1": "123","Key2": "456","Key3": "789"}
      },
      "詳細データ": [
        {"年月日": "20151005","データ": "ABCDEFG"},
        {"年月日": "20160211","データ": "HIJKLMN"},
        {"年月日": "20170802","データ": "OPQRSTU"}
      ],
      "備考": "テストデータ"
    }
  }
}

以下のように出力されます。

Property Name = ユーザーID
ユーザーID Value = USER01
Property Name = データ
Property Name = ヘッダ
Property Name = ID
ID Value = A0001
Property Name = パスワード
パスワード Value = xxxx
Property Name = パラメータ
Property Name = 共通部
Property Name = 区分
区分 Value = TEST
Property Name = プログラムID
プログラムID Value = PP01
Property Name = 機能コード
機能コード Value = 01
Property Name = 受付日
受付日 Value = 20171221
Property Name = キー値
Property Name = Key1
Key1 Value = 123
Property Name = Key2
Key2 Value = 456
Property Name = Key3
Key3 Value = 789
Property Name = 詳細データ
Array Start >>>
Property Name = 年月日
年月日 Value = 20151005
Property Name = データ
データ Value = ABCDEFG
Property Name = 年月日
年月日 Value = 20160211
Property Name = データ
データ Value = HIJKLMN
Property Name = 年月日
年月日 Value = 20170802
Property Name = データ
データ Value = OPQRSTU
<<< Array End
Property Name = 備考
備考 Value = テストデータ

以上。


<スポンサーリンク>


0 件のコメント :

コメントを投稿