c# - 如何反序列化对象结构未知的 JSON 对象

标签 c# json json.net

我的部分代码将机器的文件路径序列化为以下格式的 JSON。我正在努力获取此 JSON 并将文件路径重新组合在一起。我正在使用 Newtonsoft JSON 库;我发现它非常适合构建 JSON。如您所见,我的 JSON 具有嵌套对象。

我拥有的 JSON:

{
  ".": {
    "proc": {
      "15": {
        "task": {
          "15": {
            "exe": {},
            "mounts": {
              "list_of_files": [
                "mounts.xml"
              ]
            },
            "mountinfo": {
              "list_of_files": [
                "mountinfo.xml"
              ]
            },
            "clear_refs": {
              "list_of_files": [
                "clear_ref.xml"
              ]
            }
          }
        }
      },
      "14": {
        "loginuid": {
          "list_of_files": [
            "loginuid.xml"
          ]
        },
        "sessionid": {
          "list_of_files": [
            "sessionid.xml"
          ]
        },
        "coredump_filter": {
          "list_of_files": [
            "coredump_filter.xml"
          ]
        },
        "io": {
          "list_of_files": [
            "io.xml"
          ]
        }
      }
    }
  }
}

我想由此生成的数组。

string[] dirArray = {
"./proc/15/task/15/exe",
"./proc/15/task/15/mounts/mounts.xml",
"./proc/15/task/15/mountinfo/mountinfo.xml",
"./proc/15/task/15/clear_refs/clear_ref.xml",
"./proc/14/loginuid/loginuid.xml",
"./proc/14/sessionid/sessionid.xml",
"./proc/14/coredump_filter/coredump_filter.xml",
"./proc/14/io/io.xml"
}

到目前为止我的努力——我将 JSON 反序列化为一个动态变量,但我不确定如何处理两个问题:

  1. 我的 JSON 格式未知,我不知道对象有多深,我该如何处理?
  2. 如何使用在运行时定义的动态变量?

编辑

抱歉,我原来的 JSON 格式是错误的,所以它不适用于 answer由 user12864 提供。我收到一个错误:无法将“Newtonsoft.Json.Linq.JArray”类型的对象转换为类型“Newtonsoft.Json.Linq.JObject”。

这是一个fiddle显示我目前所处的位置。

最佳答案

@user12864在他的回答中有正确的想法,但需要调整代码以说明每个目录都可以有一个文件数组而不是单个"file"对象(你真的应该在你的问题中提到过)。这是处理该问题的更新方法:

private static void AddToFileList(JObject jo, List<string> list, string prefix)
{
    foreach (var kvp in jo)
    {
        if (kvp.Key == "list_of_files")
        {
            foreach (string name in (JArray)kvp.Value)
            {
                list.Add(prefix + name);
            }
        }
        else
        {
            JObject dir = (JObject)kvp.Value;
            if (dir.Count == 0)
            {
                list.Add(prefix + kvp.Key);
            }
            else
            {
                AddToFileList(dir, list, prefix + kvp.Key + "/");
            }
        }
    }
}

完整演示:

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

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
          ""."": {
            ""proc"": {
              ""15"": {
                ""task"": {
                  ""15"": {
                    ""exe"": {},
                    ""mounts"": {
                      ""list_of_files"": [
                        ""mounts.xml""
                      ]
                    },
                    ""mountinfo"": {
                      ""list_of_files"": [
                        ""mountinfo.xml""
                      ]
                    },
                    ""clear_refs"": {
                      ""list_of_files"": [
                        ""clear_ref.xml""
                      ]
                    }
                  }
                }
              },
              ""14"": {
                ""loginuid"": {
                  ""list_of_files"": [
                    ""loginuid.xml""
                  ]
                },
                ""sessionid"": {
                  ""list_of_files"": [
                    ""sessionid.xml""
                  ]
                },
                ""coredump_filter"": {
                  ""list_of_files"": [
                    ""coredump_filter.xml""
                  ]
                },
                ""io"": {
                  ""list_of_files"": [
                    ""io.xml""
                  ]
                }
              }
            }
          }
        }";

        JObject jo = JObject.Parse(json);
        foreach (string path in CreateFileList(jo))
        {
            Console.WriteLine(path);
        }
    }

    private static List<string> CreateFileList(JObject jo)
    {
        List<string> ret = new List<string>();
        AddToFileList(jo, ret, "");
        return ret;
    }

    private static void AddToFileList(JObject jo, List<string> list, string prefix)
    {
        foreach (var kvp in jo)
        {
            if (kvp.Key == "list_of_files")
            {
                foreach (string name in (JArray)kvp.Value)
                {
                    list.Add(prefix + name);
                }
            }
            else
            {
                JObject dir = (JObject)kvp.Value;
                if (dir.Count == 0)
                {
                    list.Add(prefix + kvp.Key);
                }
                else
                {
                    AddToFileList(dir, list, prefix + kvp.Key + "/");
                }
            }
        }
    }
}

输出:

./proc/15/task/15/exe
./proc/15/task/15/mounts/mounts.xml
./proc/15/task/15/mountinfo/mountinfo.xml
./proc/15/task/15/clear_refs/clear_ref.xml
./proc/14/loginuid/loginuid.xml
./proc/14/sessionid/sessionid.xml
./proc/14/coredump_filter/coredump_filter.xml
./proc/14/io/io.xml

fiddle :https://dotnetfiddle.net/r8CkI2

关于c# - 如何反序列化对象结构未知的 JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26717289/

相关文章:

c# - 如何使用 Json 对象映射 ValueInjecter?

c# - 在 SQL Server 中插入时,如何处理数据表中的 NULL 值变成丢失的 XML 元素?

c# - 更改特定类型(不是我的)的 JSON.NET 序列化

c# - JsonSerializerSettings 线程安全吗?

c# - 解析动态 JSON

c# - 脚手架数据库错误

javascript - 使用 Blazor 重写 JavaScript 单击和显示 UI

json - 如何将变量的值保留在函数之外?

javascript - 检查对象是否不包含不起作用的值(JS)

javascript - jmeter修改json GET结果并在PUT中使用