从这个Answer我学会了如何在c#中展平JSON对象。 来自JSON字符串:
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
要:
以下是字符串行,而不是对象
menu.id:file
menu.value:File
menu.popup.menuitem[0].value:New
menu.popup.menuitem[0].onclick:CreateNewDoc()
menu.popup.menuitem[1].value:Open
menu.popup.menuitem[1].onclick:OpenDoc()
menu.popup.menuitem[2].value:Close
menu.popup.menuitem[2].onclick:CloseDoc()
现在,我想逆转这个过程。 我可以从这个question找到实现,但它是在JavaScript中。
我如何 unflatten (从行返回结构化JSON)在C#中使用json.net?
答案 0 :(得分:2)
我设法解决了。
以下是我的代码与Sarath Rachuri's flattening code的结合。
我没有在很多情况下测试它,所以它可能是错误的。
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace JSONHelper
{
class JSONFlattener
{
private enum JSONType{
OBJECT, ARRAY
}
public static Dictionary<string, string> Flatten(JObject jsonObject)
{
IEnumerable<JToken> jTokens = jsonObject.Descendants().Where(p => p.Count() == 0);
Dictionary<string, string> results = jTokens.Aggregate(new Dictionary<string, string>(), (properties, jToken) =>
{
properties.Add(jToken.Path, jToken.ToString());
return properties;
});
return results;
}
public static JObject Unflatten(IDictionary<string, string> keyValues)
{
JContainer result = null;
JsonMergeSettings setting = new JsonMergeSettings();
setting.MergeArrayHandling = MergeArrayHandling.Merge;
foreach (var pathValue in keyValues)
{
if (result == null)
{
result = UnflatenSingle(pathValue);
}
else
{
result.Merge(UnflatenSingle(pathValue), setting);
}
}
return result as JObject;
}
private static JContainer UnflatenSingle(KeyValuePair<string, string> keyValue)
{
string path = keyValue.Key;
string value = keyValue.Value;
var pathSegments = SplitPath(path);
JContainer lastItem = null;
//build from leaf to root
foreach (var pathSegment in pathSegments.Reverse())
{
var type = GetJSONType(pathSegment);
switch (type)
{
case JSONType.OBJECT:
var obj = new JObject();
if (null == lastItem)
{
obj.Add(pathSegment,value);
}
else
{
obj.Add(pathSegment,lastItem);
}
lastItem = obj;
break;
case JSONType.ARRAY:
var array = new JArray();
int index = GetArrayIndex(pathSegment);
array = FillEmpty(array, index);
if (lastItem == null)
{
array[index] = value;
}
else
{
array[index] = lastItem;
}
lastItem = array;
break;
}
}
return lastItem;
}
public static IList<string> SplitPath(string path){
IList<string> result = new List<string>();
Regex reg = new Regex(@"(?!\.)([^. ^\[\]]+)|(?!\[)(\d+)(?=\])");
foreach (Match match in reg.Matches(path))
{
result.Add(match.Value);
}
return result;
}
private static JArray FillEmpty(JArray array, int index)
{
for (int i = 0; i <= index; i++)
{
array.Add(null);
}
return array;
}
private static JSONType GetJSONType(string pathSegment)
{
int x;
return int.TryParse(pathSegment, out x) ? JSONType.ARRAY : JSONType.OBJECT;
}
private static int GetArrayIndex(string pathSegment)
{
int result;
if (int.TryParse(pathSegment, out result))
{
return result;
}
throw new Exception("Unable to parse array index: " + pathSegment);
}
}
}
答案 1 :(得分:0)
如果我正确理解了您的需求,建议您阅读有关JObject的文档,您可以在其中找到FromObject
方法。这似乎就是你想要的。
var result = JObject.FromObject(obj);
var json = result.ToString();
答案 2 :(得分:0)
string json = JsonConvert.SerializeObject(menu);
从Nuget Package Manager获取NewtonSoft.Json dll。并写上面的那一行。
答案 3 :(得分:-1)
展平JSON对象:
arrayJSON.stringify()