我有一个看起来像
的文本文件tabs.main="******"
tabs.settings="******"
settings.setting1="******"
settings.setting2="******"
settings.setting3="******"
settings.setting4="******"
settings.setting5.title="******"
settings.setting5.settingoption1="******"
settings.setting5.settingoption2="******"
我希望能够将其解析为多层次的词典。例如,我有一个类似于Dictionary<string, object>
的根词典,并且我会有自己的Dictionary<string, object>
选项卡和设置。以图形的形式,我想要的是:
Dictionary<string, object>
-> Dictionary<"tabs", object>
-> Dictionary<"main", "*******">
-> Dictionary<"settings", "*******">
-> Dictionary<"settings", object>
-> Dictionary<"setting1", "*******">
依此类推。这可能吗?如果是这样,有人可以给我指向正确的方向。
答案 0 :(得分:2)
字典并非真正用于以这种方式保存您的数据。您可以创建表示文件的类,并将数据加载到文件中。根据你所展示的内容,这可能有用。
public class File
{
private List<Setting> settings = new List<Setting>();
public Tab Tab { get; set; }
public List<Setting> Settings { get{ return settings; } }
}
public class Tab
{
public string Main{ get; set;}
public string Settings{ get; set;}
}
public class Setting
{
private List<string> options = new List<string>();
public string Value{ get; set; }
public List<string> Options{ get{ return options;} }
}
答案 1 :(得分:1)
您将遇到的问题是,您的某些密钥需要存储在字典中,其中包含值(可能是字符串),其中一些密钥需要与字典一起存储。
在您的示例中列出了:
settings.setting5="******"
settings.setting5.settingoption1="******"
这两条线相互矛盾。 settings.settings5将使键设置5在字典中存储一个值,但下一行是期望settings5是其他值的字典。
您可以编写一段代码:
var settings = new Dictionary<string, object>();
var lines = File.ReadAllLines("...");
foreach (var line in lines)
{
var parts = line.Split(new char[] { '=' }, 2);
if (parts.Length != 2) continue;
var keys = parts[0].Split('.');
var value = parts[1];
var dict = settings;
for (int i = 0; i < keys.Length - 1; i++)
{
if (!dict.ContainsKey(keys[i]))
dict.Add(keys[i], new Dictionary<string, object>());
dict = (Dictionary<string, object>)dict[keys[i]];
}
dict.Add(keys[keys.Length - 1], value);
}
无论哪种方式,你都会发现你很可能会为此避免尝试创建字典词典。
答案 2 :(得分:0)
请考虑使用字典以外的对象,但要回答您的问题。
请注意,此数据结构不允许字典和具有相同键的字符串值。
static Dictionary<string,object> Parse(string contents)
{
var root = new Dictionary<string,object>();
using (var rdr = new StringReader(contents))
{
string line;
var equals = new [] {'='};
while(null != (line = rdr.ReadLine()))
{
if(!string.IsNullOrEmpty(line))
{
var keyValue = line.Split(equals, 2);
AddValue(root, keyValue[0], keyValue[1]);
}
}
}
return root;
}
static void AddValue(Dictionary<string,object> dict, string dottedKeys, string value)
{
string [] keys = dottedKeys.Split('.');
for(var i = 0; i < keys.Length - 1; i++)
{
var key = keys[i];
dict = GetOrAdd(dict, key);
}
dict[keys[keys.Length - 1]] = value;
}
static Dictionary<string,object> GetOrAdd(Dictionary<string,object> parent, string key)
{
object o;
Dictionary<string,object> childDict;
if(parent.TryGetValue(key, out o))
childDict = (Dictionary<string,object>) o; // This will throw when adding a dictionary to a value.
else
parent[key] = childDict = new Dictionary<string,object>();
return childDict;
}
static string fileContents=@"
tabs.main=""******""
tabs.settings=""******""
settings.setting1=""******""
settings.setting2=""******""
settings.setting3=""******""
settings.setting4=""******""
settings.setting5=""******""
settings.setting6.settingoption1=""******""
settings.setting6.settingoption2=""******""
";
答案 3 :(得分:0)
我实际上最终还是设法自己修改了一些代码,但是由于我不想浪费时间来回答这个问题,我会将Jason的问题标记为答案,因为它有点像我提出的那样。他帮我写了我的代码!
Dictionary<string, object> _dic = new Dictionary<string, object>();
using(StreamReader reader = new StreamReader(file))
{
string text;
while ((text = reader.ReadLine()) != null)
{
if (text.Equals(String.Empty))
continue;
string line = text.Trim();
string[] keyval = line.Split('=');
string value = keyval[1].Trim('"');
string[] keys = keyval[0].Split('.');
Dictionary<string, object> prevDic = _dic;
for (int i = 0; i < keys.Length; i++)
{
if (i + 1 != keys.Length)
{
Dictionary<string, object> temp = new Dictionary<string, object>();
if (prevDic.ContainsKey(keys[i]))
{
prevDic = prevDic[keys[i]] as Dictionary<string, object>; // Avoids exceptions when trying to cast the string value to a dictionary
continue;
}
else
{
prevDic.Add(keys[i], temp);
prevDic = temp;
}
}
else
{
prevDic.Add(keys[i], value);
}
}
}
}
感谢大家的帮助!