我想将json属性(名称和值)或json数据(数组)添加到现有的json字符串。
用户必须指定一个json路径来指定添加位置。
有人可以帮我提供一个链接/示例来推进此进展。
此致 阿玛尔
答案 0 :(得分:1)
您可以使用Newtonsoft.Json:
var input = "{ test: true }";
var jObject = JObject.Parse(input);
jObject["updated"] = true;
jObject["array"] = new JArray("item1", "item2", "item3");
var s = jObject.ToString();
// { test: true, updated: true, array: ["item1", "item2", "item3"] }
Console.WriteLine(s);
上面我们已经将json字符串解析为JObject
然后使用该JObject我们可以通过添加字段等来开始修改它。然后返回字符串表示我们只调用ToString
在JObject上。
答案 1 :(得分:0)
编辑:谷歌搜索了一下之后我注意到了.SelectToken()
!这是我在提到XPath时所考虑的内容。
// Inpup JSON
string input = "{ body: { name: { firstname: 'John', lastname: 'Doe' }, age: 43 } }";
JToken json = JToken.Parse(input); // Parsed to JToken as type may not be known.
// Select token based on JSONPath, see: http://goessner.net/articles/JsonPath/
JToken nameToken = json.SelectToken("$['body']['name']");
nameToken["middlename"] = "something";
// Prints: {"body":{"name":{"firstname":"John","lastname":"Doe","middlename":"something"},"age":43}}
string output = json.ToString(Newtonsoft.Json.Formatting.None);
<强> OLD:强>
看起来你想要像Jath的XPath。那么你可以找到一个现有的对象/数组并添加到那个?
我的建议是为Json搜索现有的路径工具。 这是一个快速而又肮脏的例子,说明了如何做到这一点:
static void Main(string[] args)
{
string input = "{ body: { name: { firstname: 'John', lastname: 'Doe' }, age: 43 } }";
JToken json = JToken.Parse(input);
UpdateJson(json, "body/name/middlename", "Something");
// {"body":{"name":{"firstname":"John","lastname":"Doe","middlename":"Something"},"age":43}}
string output = json.ToString(Newtonsoft.Json.Formatting.None);
UpdateJson(json, "body/jobs", new JArray(){ "C# Dev", "Network Master" });
// {"body":{"name":{"firstname":"John","lastname":"Doe","middlename":"Something"},"age":43,"jobs":["C# Dev","Network Master"]}}
string output2 = json.ToString(Newtonsoft.Json.Formatting.None);
}
private static void UpdateJson(JToken source, string path, JToken value)
{
UpdateJsonInternal(source, path.Split('/'), 0, value);
}
private static void UpdateJsonInternal(JToken source, string[] path, int pathIndex, JToken value)
{
if (pathIndex == path.Length - 1)
{
if (source is JArray)
{
((JArray)source)[int.Parse(path[pathIndex])] = value;
}
else if (source is JObject)
{
((JObject)source)[path[pathIndex]] = value;
}
}
else if (source is JArray)
{
UpdateJsonInternal(((JArray)source)[int.Parse(path[pathIndex])], path, pathIndex + 1, value);
}
else if (source is JObject)
{
UpdateJsonInternal(((JObject)source)[path[pathIndex]], path, pathIndex + 1, value);
}
}
}
这将在指定的路径上添加或更新具有JToken值的源。 所以&#39; body / name / middlename&#39;要么添加&#39;中间名&#39;名字&#39;或者使用&#39; value&#39;进行更新。如果&#39; name&#39;如果不存在,这个例子就失败了。
答案 2 :(得分:0)
如果你想设置一个存在的路径位置,你可以使用SelectToken
:
void SetValueByPath(JToken token, string path, object value)
{
var newToken = value == null ? null : JToken.FromObject(value);
var targetToken = token.SelectToken(path);
if(targetToken.Type == JTokenType.Property)
targetToken.Replace(newToken)
}
但是如果你想设置一个不存在的路径位置,这里是代码:
//Origin code by Squirrel.Downy(Flithor)
public static void AddTokenByPath(JToken jToken, string path, object value)
{
// Regex.Split("a.b.d[1]['my1.2.4'][4].af['micor.a.ee.f'].ra[6]", @"(?=\[)|(?=\[\.)|(?<=])(?>\.)")
// > { "a.b.d", "[1]", "['my1.2.4']", "[4]", "af", "['micor.a.ee.f']", "ra", "[6]" }
var pathParts = Regex.Split(path, @"(?=\[)|(?=\[\.)|(?<=])(?>\.)").ToArray();
JToken node = jToken;
for (int i = 0; i < pathParts.Length; i++)
{
var pathPart = pathParts[i];
var partNode = node.SelectToken(pathPart);
//node is null or token with null value
if (partNode == null || partNode.Type == JTokenType.Null)
{
if (i < pathParts.Length - 1)
{
//the next level is array or object
//accept [0], not ['prop']
JToken nextToken = Regex.IsMatch(pathParts[i + 1], @"\[\d+\]")) ?
new JArray() : new JObject();
SetToken(node, pathPart, nextToken);
}
else if (i == pathParts.Length - 1)
{
//JToken.FromObject(null) will throw a exception
var jValue = value == null ?
null : JToken.FromObject(value);
SetToken(node, pathPart, jValue);
}
partNode = node.SelectToken(pathPart);
}
node = partNode;
}
//set new token
void SetToken(JToken node, string pathPart, JToken jToken)
{
if (node.Type == JTokenType.Object)
{
//get real prop name (convert "['prop']" to "prop")
var name = pathPart.Trim('[', ']', '\'');
((JObject)node).Add(name, jToken);
}
else if (node.Type == JTokenType.Array)
{
//get real index (convert "[0]" to 0)
var index = int.Parse(pathPart.Trim('[', ']'));
var jArray = (JArray)node;
//if index is bigger than array length, fill the array
while (index >= jArray.Count)
jArray.Add(null);
//set token
jArray[index] = jToken;
}
}
}