我的部分代码将机器的文件路径序列化为JSON,格式如下。我正在努力采用这个JSON并将文件路径重新组合在一起。我正在使用Newtonsoft JSON lib;我发现它非常适合构建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反序列化为动态变量,但我不确定如何处理两个问题:
答案 0 :(得分:2)
这应该准确地给出你正在寻找的东西;只需使用JObject
创建JObject.Parse
并将其传递给CreateFileList
。它不会以任何好的方式处理格式错误的JSON。
static List<string> CreateFileList(JObject j)
{
List<string> ret = new List<string>();
AddToFileList(j, ret, "");
return ret;
}
static void AddToFileList(JObject j, List<string> dest, string prefix)
{
if (prefix.Length != 0)
prefix = prefix + '/';
foreach (var kvp in j)
{
var jnext = (JObject)kvp.Value;
if (kvp.Key == "file")
dest.Add(prefix + (string)jnext["name"]);
else
AddToFileList(jnext, dest, prefix + kvp.Key);
}
}
处小提琴
答案 1 :(得分:2)
@user12864在他的回答中有正确的想法,但需要调整代码以解释每个目录可以有一个文件数组而不是单个&#34;文件&#34;对象(你真的应该在最初的问题中提到过)。这是一个更新的方法来处理:
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
答案 2 :(得分:0)
<强>更新强>
在您澄清了以下要求之后,这是一个修订后的答案:
JavaScript Object Notation构建在服务器上,由用户通过分层树接口组件进行编辑。这可以非常容易地抓取。
因此,从本质上讲,您使用的是一个组件,您希望在该组件中构建从组件派生的简单JavaScript Object Notation。您的用户界面将是未知的,因此我会做出一些假设。
构建我们的对象:
public class XmlPath
{
public string Location { get; set; }
}
XmlPath
将代表我们的对象。这将是基本的汽车财产。
向我们的对象添加内容:
private List<XmlPath> AddXmlPath(List<string> location)
{
List<XmlPath> content = new List<XmlPath>();
foreach(string item in location)
content.Add(new XmlPath() { Location = item });
return content;
}
这将是一种非常简单的方法,需要大量List<string>
的用户数据并将其添加到XmlPath
对象中。
从我们的对象中删除内容:
private List<XmlPath> RemoveXmlPath(List<XmlPath> root, string location)
{
root.Remove(new XmlPath() { Location = location });
return root;
}
这两种方法真的不需要,我只是在展示和展示你的能力。此外,它将概述您更容易实现的意图。请注意这是非常原始的方法。
将我们的对象序列化/反序列化为JavaScript异议表示法:
JavaScriptSerializer serializer = new JavaScriptSerializer();
var xmlPath = AddXmlPath(List<string> location);
var result = serializer.Serialize(xmlPath);
var deserialize = serializer.Deserialize(List<XmlPath>>(result);
我们的内容现在通过基本循环公开:
foreach(XmlPath item in deserialize)
{
// Exposed Model via 'item.Location'
}
您只需将此核心功能与您的实施相关联即可。这种方法粗糙,相当简陋,绝对需要改进生产。但是,这应该让你开始:
希望这对你更好。