以下是我的JSON:
[
{
"name": "Node-1",
"flag": true,
"myObj": {
region: {
info: {
name: null,
infoFlag: false,
}
}
},
"nodes": [
{
"name": "Node-1-1",
"flag": true,
"myObj": {
region: {
info: {
name: "abc",
infoFlag: false,
}
}
},
"nodes": [
{
"name": "Node-1-1-1",
"flag": true,
"myObj": {
region: {
info: {
name: "xyz",
infoFlag: false,
}
}
},
"nodes": [
]
}
]
}
]
}
]
我想使用以下规则更新上述JSON字符串的两个属性:
举报:我想盲目地将此属性更新为false
。
infoFlag:如果name
的{{1}}属性为info
,那么我想将null
更新为infoFlag
其他{{ 1}}如果是true
。
因此,在使用这些规则更新我的JSON之后,我希望将JSON作为字符串。
注意:我不想反序列化然后根据上述两条规则更新属性,因为我的JSON有很多属性,我不想创建类,所以我是寻找可以在没有反序列化的情况下工作的东西。
这就是我尝试这样做的方式:
false
但是我在这里并没有像递归地遍历我的JSON那样;你可以看到我有如下的递归结构:
not null
答案 0 :(得分:2)
如果我已经理解了你的需求,那么这段代码非常冗长,而且不那么优雅但是很有效:
JArray temp = JArray.Parse(json);
foreach (JToken tk in temp.Descendants())
{
if (tk.Type == JTokenType.Property)
{
JProperty p = tk as JProperty;
if (p.Name == "flag")
{
if ((bool)p.Value.ToObject(typeof(bool)) == true)
p.Value = false;
}
if ((p.Name == "info") && p.HasValues)
{
bool flag = false;
foreach (JToken tkk in p.Descendants())
{
if (tkk.Type == JTokenType.Property)
{
JProperty pp = tkk as JProperty;
if ((pp.Name == "name") && (pp.Value.Type == JTokenType.Null))
{
flag = true;
}
if ((pp.Name == "infoFlag"))
{
pp.Value = (flag == true) ? true : false;
}
}
}
}
}
}
json = temp.ToString();
这是结果输出:
[
{
"name": "Node-1",
"flag": false,
"myObj": {
"region": {
"info": {
"name": null,
"infoFlag": true
}
}
},
"nodes": [
{
"name": "Node-1-1",
"flag": false,
"myObj": {
"region": {
"info": {
"name": "abc",
"infoFlag": false
}
}
},
"nodes": [
{
"name": "Node-1-1-1",
"flag": false,
"myObj": {
"region": {
"info": {
"name": "xyz",
"infoFlag": false
}
}
},
"nodes": []
}
]
}
]
}
]
答案 1 :(得分:1)
Json.NET允许您将表示JSON内容的内部对象视为dynamic
,这使得有问题的任务不会比使用常规类型对象更难。
唯一一个棘手的问题是递归对象结构(nodes
数组),但这不是JSON或dynamic
特定问题,可以通过多种方式解决 - 明显的递归方法或者我的首选树展平枚举(我对How to flatten tree via LINQ?的回答中的Expand
方法)。
话虽如此,解决方案可能是这样的:
var array = JArray.Parse(json);
var nodes = array.Cast<dynamic>().Expand(x => x.nodes);
foreach (var node in nodes)
{
node.flag = true;
var info = node.myObj.region.info;
info.infoFlag = (info.name == null);
}
var newJson = array.ToString();