🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JSON

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

1回答

3405閲覧

ネストされたJSONのプロパティ名を取得したい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JSON

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

1クリップ

投稿2019/10/16 06:15

編集2019/10/16 08:18

こんにちは。
windowsフォームでOpenFileDialogでjsonファイルを選択して読み込みグリッドビューに表示したいと思っています。
読み込むjsonが決まっていれば良いのですが中身が固定ではないため、それぞれにあったカラムを用意したいと思います。
そこでjsonのキー値をカラム名にすべく取得したいのですが入れ子になっている部分のプロパティ名が取れません。
中身が固定ではないためキー値を直接指定するようなソースではないものを探しています。
ネットを参考に以下のコードを書きました。
JTokenTypeによってそのままプロパティ名を出力するか更に掘り下げるか決めます。

C#

1// reader.ReadToEnd()でjsonファイルを読み込む 2JObject obj = JObject.Parse(reader.ReadToEnd()); 3 4List<string> keys = getValue(obj); 5 6 private List<string> getValue(JObject jObj) 7 { 8 List<string> plist = new List<string>(); 9 10 var jobj = jObj.Children(); 11 12 foreach (JToken jt in (JEnumerable<JToken>)jobj) 13 { 14 if (JTokenType.Object != jt.Type) 15 { 16 if (JTokenType.Property == jt.Type) 17 { 18 var jp = (JProperty)jt; 19 plist.Add(jp.Name); 20 } 21 else if(JTokenType.Array == jt.Type) 22 { 23 foreach(JToken JArr in jt.ToArray<JToken>()) 24 { 25 getValue((JObject)JArr); 26 } 27 } 28 else 29 { 30 plist.Add(jt.ToString()); 31 } 32 } 33 else 34 { 35 getVlue((JObject)jt); 36 } 37 } 38 return plist; 39 }

しかしitemId01,itemId02,itemId03という風に取れて欲しかったのですが。下記の”items”という値しか取れませんでした。
JTokenTypeがプロパティで取れているようでした。
ネストしている部分がJTokenType.Arrayと認識されるには何か条件があるのでしょうか?
またjsonのキー値をネストにかかわらず全て取得する方法があればどうかご教授お願いします。

json(例)

1{ 2 "items": [ 3 { 4 "itemId01": "item01", 5 "itemName01": "商品01" 6 }, 7 { 8 "itemId02": "item02", 9 "itemName02": "商品02" 10 }, 11 { 12 "itemId03": "item03", 13 "itemName03": "商品03" 14 } 15 ] 16}

追記
Json.NET6.0(ラインタイムバージョン4.0.30319)を利用しています。
jsonの内容にかかわらずプロパティ名が取れるような方法を探しています。上記の例ではitemid01やitemnameという要素がありますが、あくまで例であり、それらキー値がわからなくてもネストしているか判断できるような方法をご存知ないでしょうか。。

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

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

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

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

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

takabosoft

2019/10/16 06:36

Json.NETを使っている等と記載しましょう(つかっているのであれば)。
退会済みユーザー

退会済みユーザー

2019/10/16 06:45

すみません。追記しました。 ありがとうございます。
退会済みユーザー

退会済みユーザー

2019/10/16 07:09

Json.NET を使うのは必須ですか?
退会済みユーザー

退会済みユーザー

2019/10/16 07:17

必須ではありません。とりあげず手段は限定しないで探しています。
guest

回答1

0

ベストアンサー

再帰を使ってください。

C#

1using System; 2using System.Linq; 3using System.Windows.Forms; 4using Newtonsoft.Json.Linq; 5 6namespace WindowsFormsApp1 7{ 8 public partial class Form1 : Form 9 { 10 public Form1() 11 { 12 InitializeComponent(); 13 } 14 15 private void Form1_Load(object sender, EventArgs e) 16 { 17 var obj = JObject.Parse(@" 18{ ""items"": [ 19 20 { 21 ""itemId01"": "" 22 ""itemName01"": ""商品01"" 23 24 }, 25 { 26 ""itemId02"": ""item02"", 27 ""itemName02"": ""商品02"" 28 29 }, 30 { 31 ""itemId03"": ""item03"", 32 ""itemName03"": ""商品03"" 33 } 34]} 35"); 36 void printKeys(JToken container) 37 { 38 switch (container) 39 { 40 case JArray a: 41 foreach (var child in a) 42 { 43 printKeys(child); 44 } 45 break; 46 case JObject o: 47 foreach (var property in o) 48 { 49 Console.WriteLine(property.Key); 50 printKeys(property.Value); 51 } 52 break; 53 default: 54 break; 55 } 56 } 57 58 printKeys(obj["items"]); 59 60 // 再帰を使わず今回の件に最適化してもっと簡単に 61 Console.WriteLine("---"); 62 var list = obj["items"] 63 .SelectMany(a => a) 64 .OfType<JProperty>() 65 .Select(a => a.Name) 66 .ToList(); 67 foreach (var item in list) 68 { 69 Console.WriteLine(item); 70 } 71 } 72 } 73} 74

投稿2019/10/16 07:28

編集2019/10/16 08:48
Zuishin

総合スコア28669

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

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

退会済みユーザー

退会済みユーザー

2019/10/16 08:02

回答ありがとうございます。 すみません、情報が不足していたので追記しました。 取得元のjsonを動的に決定したいためitemidという名前を含んでいるか直接見るような方法ができないのです。 どの部分がネストしているかは時と場合によって変わる状態です 該当部分を他に置き換えるような方法はありますでしょうか?
Zuishin

2019/10/16 08:04

これはあくまで例です。 itemId と itemName と二つありますが、どちらか片方だけが必要なんでしょう? どちらが必要かという条件がこちらには示されていないので、それはそちらで適応させてください。 できないなら、もともと不可能だったということになりませんか?
Zuishin

2019/10/16 08:20

質問が変わったので、対応させました。itemId であろうがなんであろうが関係なく表示します。
退会済みユーザー

退会済みユーザー

2019/10/16 08:43

情報が不足していてすみませんでした。 実行したところ、無事自分の求めていた挙動になりました! JTokenの状態から場合分けすべきだったのですね、もっとオブジェクトの仕組みを勉強します。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問