C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: JSONデータの変換


(過去ログ 178 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■102170 / inTopicNo.1)  JSONデータの変換
  
□投稿者/ だい (1回)-(2023/07/14(Fri) 00:12:02)

分類:[C#] 

Windows10のVisual Studio 2022でWindowsアプリケーションを .NET Framework 4.7.2で作っています。

"AAA":{"111":1,"222":1,"333":1}

上記のJSONデータを

"AAA":[111,222,333]

という形でキーの値を数値に変換し配列で表記したいのですが変換する方法がわかりません。
元のJSONの値は使用しません。キーの値は必ず数字なので変換後は数字になります。

どなたかわかる方ご教示お願いします。

引用返信 編集キー/
■102171 / inTopicNo.2)  Re[1]: JSONデータの変換
□投稿者/ WebSurfer (2742回)-(2023/07/14(Fri) 07:30:17)
No102170 (だい さん) に返信

> "AAA":{"111":1,"222":1,"333":1}
>
> 上記のJSONデータを
>
> "AAA":[111,222,333]
>
> という形でキーの値を数値に変換し配列で表記したいのですが変換する方法がわかりません。
> 元のJSONの値は使用しません。

「変換する」のに「元のJSONの値は使用しません」とはどういうことですか? 意味がわかりません。

ひょっとして、.NET オブジェクトからシリアライズして、

> "AAA":[111,222,333]

としたいということですか?

引用返信 編集キー/
■102172 / inTopicNo.3)  Re[1]: JSONデータの変換
□投稿者/ WebSurfer (2743回)-(2023/07/14(Fri) 09:44:42)
No102170 (だい さん) に返信

さらに、

> "AAA":{"111":1,"222":1,"333":1}

も、

> "AAA":[111,222,333]

も JSON としては不正です。直してください。
引用返信 編集キー/
■102173 / inTopicNo.4)  Re[1]: JSONデータの変換
□投稿者/ 魔界の仮面弁士 (3669回)-(2023/07/14(Fri) 10:33:58)
No102170 (だい さん) に返信
> "AAA":{"111":1,"222":1,"333":1}
> "AAA":[111,222,333]
JSON ならば、両端が『{〜}』か『"〜"』か『[〜]』のいずれになるはず。

実際には『{"AAA":{"111":1,"222":1,"333":1}}』を
『{"AAA":[111,222,333]}』にしたいのではありませんか?



JavaScript で処理するなら、
 const jsSrc = '{"AAA":{"111":1,"222":1,"333":1}}';
 const jsDst = JSON.stringify({AAA:Object.keys(JSON.parse(jsSrc).AAA).map(n => parseInt(n, 10))});
と書けます。


C#7.3 + .NET Framework 4.7.2 であれば
 const string jsSrc = @"{""AAA"":{""111"":1,""222"":1,""333"":1}}";
に対して、
 /* Newtonsoft.json 13.0.3 を使う場合 */
 // using Newtonsoft.Json.Linq;
 JObject oDst = JObject.FromObject(new { AAA = JObject.Parse(jsSrc)["AAA"].Children<JProperty>().Select(p => int.Parse(p.Name)) });
 string jsDst = oDst.ToString(Newtonsoft.Json.Formatting.None);
あるいは
 /* System.Text.Json 7.0.3 を使う場合 */
 // using System.Text.Json.Nodes;
 JsonObject oDst = new JsonObject { ["AAA"] = new JsonArray(JsonNode.Parse(jsSrc)["AAA"].AsObject().Select(p => (JsonNode)int.Parse(p.Key)).ToArray()) };
 string jsDst = oDst.ToJsonString();
と書けます。
引用返信 編集キー/
■102174 / inTopicNo.5)  Re[1]: JSONデータの変換
□投稿者/ WebSurfer (2744回)-(2023/07/14(Fri) 13:30:51)
No102170 (だい さん) に返信

> "AAA":{"111":1,"222":1,"333":1}
>
> 上記のJSONデータを
>
> "AAA":[111,222,333]
>
> という形でキーの値を数値に変換し配列で表記したいのですが変換する方法がわかりません。
> 元のJSONの値は使用しません。

「変換する」のに「元のJSONの値は使用しません」ということの意味が不明ですし、
上の質問者さんが JSON と言っている文字列は JSON としては不正ですが、

{"AAA":{"111":1,"222":1,"333":1}} という JSON 文字列から、.NET オブジェクト 
(JSON で言うと {"AAA":[111,222,333]} という内容の) を作って、質問者さんの作
っている「Windowsアプリケーション」で使いたいということではなかろうかと想像
してレスします。

.NET Framework 4.7.2 とのことですので Microsoft が推奨している System.Text.Json
名前空間の JsonSerializer を使うのが良さそうです。NuGet からインストールして
ください。

JsonSerializer を使って {"AAA":{"111":1,"222":1,"333":1}} を JsonElement に
デシリアライズし、それを細工して .NET オブジェクトを作成してはいかがですか?

JsonElement 構造体
https://docs.microsoft.com/ja-jp/dotnet/api/system.text.json.jsonelement

以下のような感じ。下の RootObject クラスが .NET オブジェクトの型です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;

namespace ConsoleAppJsonNet472
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string json = "{\"AAA\":{\"111\":1,\"222\":1,\"333\":1}}";

            // 上の JSON 文字列を JsonElement にデシリアライズ
            JsonElement jelem = JsonSerializer.Deserialize<JsonElement>(json);

            // 上で取得した JsonElement の中の {"111":1,"222":1,"333":1} の部分を
            // JsonElement として取得 
            JsonProperty root = jelem.EnumerateObject().First();
            JsonElement value = root.Value;

            // {"111":1,"222":1,"333":1} の name の部分 ("111", "222", "333") 
            // の各文字列を int にパースして List<int> 型オブジェクトを作成
            List<int> list = new List<int>();
            foreach (JsonProperty jprop in value.EnumerateObject())
            {
                // jprop.Name は "111", "222", "333" の部分
                list.Add(int.Parse(jprop.Name));
            }

            // .NET オブジェクトを作成
            RootObject rootObject = new RootObject();
            rootObject.AAA = list;

            // JSON 文字列 {"AAA":[111,222,333]} が必要なら上の .NET オブジェクト
            // をシリアライズして作成
            String newJson = JsonSerializer.Serialize<RootObject>(rootObject);
        }
    }

    public class RootObject
    {
        public List<int> AAA { get; set; }
    }
}

引用返信 編集キー/
■102175 / inTopicNo.6)  Re[2]: JSONデータの変換
□投稿者/ だい (3回)-(2023/07/14(Fri) 20:46:26)
皆様回答ありがとうございます。
元データは外部から取り込んだデータで正式なJSON形式ではないのでこれをJSON形式に変換したかったのです。

取り込んだデータは
{"99":{"id_1":{"101":1,"102":1,"103":1,"104":1,"105":1,"106":1},"id_2":{"201":1,"202":1,"203":1},"id_3":{"301":1}}}
このような形式で構成されており
{"99":{"id_1":null,"id_2":{"201":1,"202":1,"203":1},"id_3":{"301":1}}}
↑のようにnullが含まれているデータもあります。

これを
{"newname":99,"id_1":[101,102,103,104,105,106],"id_2":[201,202,203],"id_3":[301]}
{"newname":99,"id_1":null,"id_2":[201,202,203],"id_3":[301]}
こういった形にする場合はどの様にすれば良いのでしょうか?

引用返信 編集キー/
■102176 / inTopicNo.7)  Re[3]: JSONデータの変換
□投稿者/ WebSurfer (2745回)-(2023/07/14(Fri) 21:10:45)
No102175 (だい さん) に返信
> 皆様回答ありがとうございます。
> 元データは外部から取り込んだデータで正式なJSON形式ではないのでこれをJSON形式に変換したかったのです。
>
> 取り込んだデータは
> {"99":{"id_1":{"101":1,"102":1,"103":1,"104":1,"105":1,"106":1},"id_2":{"201":1,"202":1,"203":1},"id_3":{"301":1}}}
> このような形式で構成されており
> {"99":{"id_1":null,"id_2":{"201":1,"202":1,"203":1},"id_3":{"301":1}}}
> ↑のようにnullが含まれているデータもあります。
>
> これを
> {"newname":99,"id_1":[101,102,103,104,105,106],"id_2":[201,202,203],"id_3":[301]}
> {"newname":99,"id_1":null,"id_2":[201,202,203],"id_3":[301]}
> こういった形にする場合はどの様にすれば良いのでしょうか?
>

話が違うよね。何で最初からそう書かないの? 腹立たしい限り。
引用返信 編集キー/
■102177 / inTopicNo.8)  Re[4]: JSONデータの変換
□投稿者/ だい (4回)-(2023/07/14(Fri) 21:38:11)
No102176 (WebSurfer さん) に返信
> ■No102175 (だい さん) に返信
>>皆様回答ありがとうございます。
>>元データは外部から取り込んだデータで正式なJSON形式ではないのでこれをJSON形式に変換したかったのです。
>>
>>取り込んだデータは
>>{"99":{"id_1":{"101":1,"102":1,"103":1,"104":1,"105":1,"106":1},"id_2":{"201":1,"202":1,"203":1},"id_3":{"301":1}}}
>>このような形式で構成されており
>>{"99":{"id_1":null,"id_2":{"201":1,"202":1,"203":1},"id_3":{"301":1}}}
>>↑のようにnullが含まれているデータもあります。
>>
>>これを
>>{"newname":99,"id_1":[101,102,103,104,105,106],"id_2":[201,202,203],"id_3":[301]}
>>{"newname":99,"id_1":null,"id_2":[201,202,203],"id_3":[301]}
>>こういった形にする場合はどの様にすれば良いのでしょうか?
>>
>
> 話が違うよね。何で最初からそう書かないの? 腹立たしい限り。


申し訳ありません。
引用返信 編集キー/
■102178 / inTopicNo.9)  Re[3]: JSONデータの変換
□投稿者/ HattariB (77回)-(2023/07/15(Sat) 02:06:40)
No102175 (だい さん) に返信

ちょっと良くわかんないんですけど、
> 元データは外部から取り込んだデータで正式なJSON形式ではないので...
「正式なJSON形式ではない!」ってのはどの辺ですか?
階層も構造も事実としてもキッチリjsonになってると思うんだけど、、、
どの辺が正式では無いのかを教えてくださいな。

nullが入ってるってのは、
その変数には何にも代入されてないからnullになってるだけじゃ無いすか?もしくはあえてnullを入れる挙動をしてるとか。。。


> 取り込んだデータは
> このような形式で構成されており
階層構造を絵に描いてみ。特に公開しなくても良いからさ。
配列と連想配列の違いを正しく認識した方が良いと思いますよ。
要は構造変換したいんですよね。


> これを
> こういった形にする場合はどの様にすれば良いのでしょうか?
連想配列のキーだけを抜き取った配列に名前を付けたいのなら、既にご回答が出てますよ。
そこを応用できないのであれば、構造の違いを明確にしてから、
コツコツと要素を代入した方が、だいさんにとってはわかりやすいんじゃぁないかな。
引用返信 編集キー/
■102179 / inTopicNo.10)  Re[2]: JSONデータの変換
□投稿者/ だい (5回)-(2023/07/15(Sat) 09:16:32)
No102174 (WebSurfer さん) に返信
> ■No102170 (だい さん) に返信
>
>>"AAA":{"111":1,"222":1,"333":1}
> >
>>上記のJSONデータを
> >
>>"AAA":[111,222,333]
> >
>>という形でキーの値を数値に変換し配列で表記したいのですが変換する方法がわかりません。
>>元のJSONの値は使用しません。
>
> 「変換する」のに「元のJSONの値は使用しません」ということの意味が不明ですし、
> 上の質問者さんが JSON と言っている文字列は JSON としては不正ですが、
>
> {"AAA":{"111":1,"222":1,"333":1}} という JSON 文字列から、.NET オブジェクト
> (JSON で言うと {"AAA":[111,222,333]} という内容の) を作って、質問者さんの作
> っている「Windowsアプリケーション」で使いたいということではなかろうかと想像
> してレスします。
>
> .NET Framework 4.7.2 とのことですので Microsoft が推奨している System.Text.Json
> 名前空間の JsonSerializer を使うのが良さそうです。NuGet からインストールして
> ください。
>
> JsonSerializer を使って {"AAA":{"111":1,"222":1,"333":1}} を JsonElement に
> デシリアライズし、それを細工して .NET オブジェクトを作成してはいかがですか?
>
> JsonElement 構造体
> https://docs.microsoft.com/ja-jp/dotnet/api/system.text.json.jsonelement
>
> 以下のような感じ。下の RootObject クラスが .NET オブジェクトの型です。
>
> using System;
> using System.Collections.Generic;
> using System.Linq;
> using System.Text.Json;
>
> namespace ConsoleAppJsonNet472
> {
> internal class Program
> {
> static void Main(string[] args)
> {
> string json = "{\"AAA\":{\"111\":1,\"222\":1,\"333\":1}}";
>
> // 上の JSON 文字列を JsonElement にデシリアライズ
> JsonElement jelem = JsonSerializer.Deserialize<JsonElement>(json);
>
> // 上で取得した JsonElement の中の {"111":1,"222":1,"333":1} の部分を
> // JsonElement として取得
> JsonProperty root = jelem.EnumerateObject().First();
> JsonElement value = root.Value;
>
> // {"111":1,"222":1,"333":1} の name の部分 ("111", "222", "333")
> // の各文字列を int にパースして List<int> 型オブジェクトを作成
> List<int> list = new List<int>();
> foreach (JsonProperty jprop in value.EnumerateObject())
> {
> // jprop.Name は "111", "222", "333" の部分
> list.Add(int.Parse(jprop.Name));
> }
>
> // .NET オブジェクトを作成
> RootObject rootObject = new RootObject();
> rootObject.AAA = list;
>
> // JSON 文字列 {"AAA":[111,222,333]} が必要なら上の .NET オブジェクト
> // をシリアライズして作成
> String newJson = JsonSerializer.Serialize<RootObject>(rootObject);
> }
> }
>
> public class RootObject
> {
> public List<int> AAA { get; set; }
> }
> }


こちらのサンプルを参考にして無事変換できました。
ありがとうございました。
解決済み
引用返信 編集キー/
■102180 / inTopicNo.11)  Re[3]: JSONデータの変換
□投稿者/ Azulean (1278回)-(2023/07/15(Sat) 09:20:47)
2023/07/15(Sat) 09:21:20 編集(投稿者)

// 入れ違いで解決してた…。

No102175 (だい さん) に返信
> 元データは外部から取り込んだデータで正式なJSON形式ではないのでこれをJSON形式に変換したかったのです。

他の方も指摘しているけれど、外部から取り込んだとされるデータ自体は JSON 形式として正しいです。
「正式な JSON 形式でない」と表現してしまっている以上は、知識不足でスタートしているのではないかな?

今回、あなたが関わっている業務か何かは、「ある JSON 形式のデータを、自分たちが望む、異なる構造の JSON 形式のデータに変換したい」です。
このため、「正式な JSON 形式に変換したい」ではなく、「別の箱に入れ換えたい」と考えるべきところです。

構造を自分好みに変えることなので、一撃ですぱっと終わるような夢のような方法はありません。
地道に、入力されうるパターンを網羅し、好む構造に入れ換えて、出力するソースコードを自分で作る必要があります。


こう考えると、残念ながら掲示板で聞くことではないかな?と思えます。
何がわからないかわかっていないと思いますし、自覚ないかと思いますが、「要求仕様を示してソースコードを作る仕事を依頼している」ことになっているためです。

業務なのであれば上司と進め方を相談してみてください。
解決済み
引用返信 編集キー/
■102181 / inTopicNo.12)  Re[3]: JSONデータの変換
□投稿者/ WebSurfer (2746回)-(2023/07/16(Sun) 11:30:53)
No102179 (だい さん) に返信

> こちらのサンプルを参考にして無事変換できました。
> ありがとうございました。

どのようにして解決できたのか、もう少し具体的に書いてもらえませんか?
引用返信 編集キー/
■102200 / inTopicNo.13)  Re[3]: JSONデータの変換
□投稿者/ WebSurfer (2749回)-(2023/07/19(Wed) 23:53:26)
No102179 (だい さん) に返信

> こちらのサンプルを参考にして無事変換できました。

ここのような Q&A サイトは、一方的に質問者が情報を得るという目的だけでなく、
技術者同士の情報交換や相互サポートを行うという目的もあるはずです。

また、後で検索などでここを訪れる人もいるかもしれません。実際、問題に遭遇し
てググって調べてヒットした記事が役に立ったという経験は皆さんお持ちのはず
です。

ということで、解決できたということだそうですので、どのように解決したのか
質問者さんも情報提供してもらえませんか?
引用返信 編集キー/
■102220 / inTopicNo.14)  Re[3]: JSONデータの変換
□投稿者/ WebSurfer (2755回)-(2023/07/28(Fri) 13:49:37)
質問者さんは No102174 を参考に解決できたそうなので、どのように解決したのか情報提供をお願い
したのですが、スレッドを放棄して去ってしまったようなので、自分が案を書いておきます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;

namespace ConsoleApp
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string json1 = "{\"99\":{\"id_1\":{\"101\":1,\"102\":1,\"103\":1,\"104\":1,\"105\":1,\"106\":1},\"id_2\":{\"201\":1,\"202\":1,\"203\":1},\"id_3\":{\"301\":1}}}";
            Console.WriteLine(Convert(json1));

            // 結果:
            // {"newname":99,"id_1":[101,102,103,104,105,106],"id_2":[201,202,203],"id_3":[301]}

            string json2 = "{\"99\":{\"id_1\":null,\"id_2\":{\"201\":1,\"202\":1,\"203\":1},\"id_3\":{\"301\":1}}}";
            Console.WriteLine(Convert(json2));

            // 結果:
            // {"newname":99,"id_1":null,"id_2":[201,202,203],"id_3":[301]}
        }

        private static string Convert(string json)
        {
            JsonElement jelem1 = JsonSerializer.Deserialize<JsonElement>(json);
            StringBuilder sb = new StringBuilder();
            sb.Append("{\"newname\":");

            foreach (JsonProperty jprop in jelem1.EnumerateObject())
            {
                sb.Append(jprop.Name);      // {"newname":99

                foreach (JsonProperty jprop1 in jprop.Value.EnumerateObject())
                {
                    if (jprop1.Value.ValueKind == JsonValueKind.Null)
                    {
                        sb.Append($",\"{jprop1.Name}\":null");  // {"newname":99,"id_1":null                   
                    }
                    else
                    {
                        sb.Append($",\"{jprop1.Name}\":[");      // {"newname":99,"id_1":[
                        foreach (JsonProperty jprop2 in jprop1.Value.EnumerateObject())
                        {
                            sb.Append($"{jprop2.Name},");   // {"newname":99,"id_1":[101,102,103,104,105,106,
                        }

                        sb.Replace(',', ']', sb.Length - 1, 1);  // {"newname":99,"id_1":[101,102,103,104,105,106]
                    }
                }
            }
            sb.Append("}");

            return sb.ToString();
        }
    }
}

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -