I have a JSON structure that contains different levels. How to iterate the JSON and get all values of a particular key in JSON in C#
Below is my JSON file
{
"name": "EPM Company",
"id": "kpfwzgmhpm",
"type": "root",
"childern": [
{
"cid": "67",
"cname": "cname1",
"childern": [
{
"reading": [
{
"id": 121,
"name": "test1"
},
{
"id": 1121,
"name": "test11"
}
]
}
]
},
{
"cid": "454",
"cname": "cname14",
"childern": [
{
"reading": [
{
"id": 454,
"name": "test14"
},
{
"id": 21,
"name": "test141"
}
]
}
]
}
]
}
This is the JSON format. I am trying to get the value in the below format.
{
"name": "EPM Company",
"id": "kpfwzgmhpm",
"value": [
{
"id": 121,
"name": "test1",
"cid": "67",
"cname": "cname1"
},
{
"id": 1121,
"name": "test11",
"cid": "67",
"cname": "cname1"
},
{
"id": 124234,
"cname": "test12342",
"cid": "67",
"name": "cname1"
},
{
"id": 454,
"name": "test14",
"cid": "454",
"cname": "cname14"
},
{
"id": 21,
"name": "test141",
"cid": "454",
"cname": "cname14"
},
{
"id": 121,
"name": "test123122",
"cid": "454",
"cname": "cname14"
}
]
}
fetching all the reading key and its value-added to array with its cid and came. is it possible?
advanced thanks for the help
my code in c# is
public string SensorList(string entireData)
{
if (string.IsNullOrEmpty(entireData))
{
return string.Empty;
}
var returnObj = new Jobject ();
JObject o = JObject.Parse(entireData);
var childern = o["children"];
returnObj.Add("name" = o ["name"];
returnObj.Add("id" = o ["id"];
returnObj.Add("value" = o ["value"];
var valuearry = new JArray();
foreach(var data in childern)
{
foreach(var reading in data["reading"])
{
var valobj = new Jobject ();
valobj.Add( "cid",data["id"])
valobj.Add( "cname",data["name"])
valobj.Add( "name",reading["id"])
valobj.Add( "id",reading["name"])
valuearry.add()
if(data.containsKey("children"))
{
var sensorInfo = SensorList(data["children"]);
}
}
returnObj.Add("value",valuearry);
// var output = sensorInfo.SelectMany(x => ((JObject)x).Properties().Select(y => new JObject {
// new JProperty("id",y.Name),
// new JProperty("name",y.Value["name"])
// })).ToList();
// var returnArray = new JArray(output);
return returnObj.ToString();
}
}
recurring part is not working and take too much time for other long JSON file
Related
the JSON below is taken from other post. My issue is I know the id and I want to find out where is it located. Eg, I got ID 19006 and I want to get Folder2. How am I going to do this.
{
"data": {
"id": 0,
"name": "",
"childFolders": [{
"id": 19002,
"name": "Locker",
"childFolders": [{
"id": 19003,
"name": "Folder1",
"childFolders": [],
"childComponents": [{
"id": 19005,
"name": "route1",
"state": "STOPPED",
"type": "ROUTE"
}]
}, {
"id": 19004,
"name": "Folder2",
"childFolders": [],
"childComponents": [{
"id": 19008,
"name": "comm1",
"state": "STOPPED",
"type": "COMMUNICATION_POINT"
}, {
"id": 19006,
"name": "route2",
"state": "STOPPED",
"type": "ROUTE"
}, {
"id": 19007,
"name": "route3",
"state": "STOPPED",
"type": "ROUTE"
}]
}],
"childComponents": []
}],
"childComponents": []
},
"error": null
}
I write code now it is like this:
var json = GetJsonString();
var model = GetJsonModel(json);
var folderName = GetName(model.data, 19006);
I chekced and code is correct. folderName is Folder2
And the recursive code:
private string GetName(Data data, int searchValue)
{
var folderName = data.name;
foreach (var item in data.childComponents)
{
if (item.id == searchValue)
{
return folderName;
}
}
if (data.childFolders.Length > 0)
{
foreach (var item in data.childFolders)
{
var folderName1 = GetName(item, searchValue);
if (folderName1 != null)
{
return folderName1;
}
}
}
return null;
}
Your model is like this:
EDIT:
I parse Json like this.
return JsonSerializer.Deserialize<YourJson>(test);
How can I delete objects having removethisobject="yes" in path rootkey3.variablekey1.properties, rootkey3.variablekey2.properties. The challenge is that rootkey3 can have keys with different name and are not fixed which means that variablekey1, variablekey2 etc. can be anything.)
changingjson
{
"rootkey1": "rv1",
"rootkey2": "rv2",
"rootkey3": {
"variablekey1": {
"childkey1": "ckv1",
"Properties": {
"Description": "g desc",
"id": "ck1id",
"fewdetails":
[
{
"removethisobject": "yes",
"name": "name1",
"age": 21
},
{
"removethisobject": "no",
"name": "name2",
"age": 22
}
],
"moredetails": [
{
"removethisobject": "yes",
"name": "namefmd1",
"age": 21
},
{
"removethisobject": "no",
"name": "namefnd2",
"age": 21
}
]
}
},
"variablekey2": {
"childkey1": "ckv2",
"Properties": {
"Description": "g desc",
"id": "ck2id",
"fewdetails": [
{
"removethisobject": "yes",
"name": "name1",
"age": 21
},
{
"removethisobject": "no",
"name": "name2",
"age": 22
}
],
"moredetails": [
{
"removethisobject": "yes",
"name": "namefmd1",
"age": 21
},
{
"removethisobject": "no",
"name": "namefnd2",
"age": 21
}
]
}
}
}
}
Tried following code in C# and get an exception
var myJobj = JObject.Parse(changingJSON);
var rk3 = myJobj.SelectToken("rootkey3");
foreach (var ck in rk3)
{
var ck1 = (string)ck["childkey1"]; // exception
}
I am using latest version of Newtonsoft and .Net fx 4.7
Try this if it can help you,
var json = File.ReadAllText("json1.json");
var myJobj = JObject.Parse(json);
var rk3 = myJobj.SelectToken("rootkey3");
foreach (var ck in rk3.Children())
{
var ck1 = ck.SelectToken("$..childkey1").ToString();
}
Here, I am trying to create a JSON using using Newtonsoft.Json; libraries. I came up with a function which partially does my job and when the same function is called, my previous data on the JObject is lost. I am new to this items JProperty, JObject, JArray, JToken however managed to come up with this code.
The parent is initiated in the function itself and when the function is recursively called its initiated and cleaned up again. So I added another JObject head. Making it more complicated.
string statment = "(Entity.Country = 'USA' AND Entity.ShortName = 'Adele' AND (Entity.CIFNumber = '12345' OR Statement.StatementYear = '2015'))";
public static JObject ConvertToJsonObject(string text)
{
JObject parent = new JObject();
string bracketContents = getWhatsInsideBrackets(text);
parent.Add(new JProperty("operator", ReturnOperator(text)));
parent.Add(new JProperty("rules"));
string[] operators = splitWithOperator(bracketContents);
List<JObject> req = new List<JObject>();
for (int i = 0; i < splitWithOperator(bracketContents).Length; i++)
{
if (!checkIfBracketsExists(operators[i].Trim()))
{
req.Add(GetEachCondition(operators, i));
}
else if (checkIfBracketsExists(operators[i]))
{
parent["rules"] = new JArray(ConvertToJsonObject(operators[i]));
head = parent;
parent["rules"] = (ConvertToJsonObject(operators[i]));
}
}
parent["rules"] = new JArray(req);
head["rules"] = parent;
return parent;
}
I am trying to achieve this JSON output: (Only trying to achieve the key, value of DataSetCommonQuery, dont worry about the other keys on the json)
{
"context": {
"wfId": "00000000-0000-0000-0000-000000000000",
"taskId": "00000000-0000-0000-0000-000000000000"
},
"payLoad": {
"DataSetCommonQuery": {
"operator": "AND",
"rules": [
{
"field": "ENTITY.CIFNumber",
"condition": "<>",
"value": "3123"
},
{
"field": "ENTITY.Country",
"condition": "LIKE",
"value": "USA"
},
{
"operator": "OR",
"rules": [
{
"field": "ENTITY.FYEMonth",
"condition": "=",
"value": "May"
},
{
"field": "STATEMENT.ProfitBeforeTax",
"condition": ">=",
"value": 123123
},
{
"field": "STATEMENT.NetSales",
"condition": "<=",
"value": 234234
},
{
"field": "STATEMENT.statementdatekey_",
"condition": "=",
"value": "2019-07-01 12:00:00"
}
]
}
]
},
"PeerType": "DEFAULT",
"Name": "API TEST",
"Description": "API TEST",
"BmkPeerFormatId": "DBBmk",
"OperationType": "Create"
}
}
When I try to query a document using a field within it that I have tried to index then RavenDB complains that it is not in fact indexed.
The document - "jobs/332" - is as follows:
{
"Type": "Outbound",
"Flight": {
"Operator": "SAS",
"Number": "267",
"Origin": "MAN",
"Gate": "019",
"Stand": "A12",
"STD": "2015-08-20T09:15:00.0000000Z",
"ETD": "2015-08-20T09:16:00.0000000Z",
"Status": "On Time",
"Seat": "16F"
},
"PAX": {
"Name": "Mr. John Smith",
"Types": [
{
"Description": "WCHC"
},
{
"Description": "DPNA"
}
],
"Prenotified": true
},
"Stages": [
{
"AssignedAgents": [
{
"Id": 34,
"Name": "Derek Brown"
}
],
"StageStart": {
"Location": "T1 Checkin",
"Time": "2015-08-20T08:00:00.0000000Z"
},
"StageEnd": {
"Location": "Lounge 1",
"Time": "2015-08-20T08:25:00.0000000Z"
}
},
{
"AssignedAgents": null,
"StageStart": {
"Location": "Lounge 1",
"Time": "2015-08-20T08:45:00.0000000Z"
},
"StageEnd": {
"Location": "Gate 019",
"Time": "2015-08-20T08:55:00.0000000Z"
}
}
]
}
I have created the following static index:
public class Job_Agent : AbstractIndexCreationTask<Job>
{
public Job_Agent()
{
Map = jobs => from job in jobs
from stage in job.Stages
from agent in stage.AssignedAgents
select new
{
agent.Id
};
}
}
When I try to query the document with the following query:
_session.Query<Job, Job_Agent>()
.First(u => u.Stages
.Any(t => t.AssignedAgents
.Any(a => a.Id == 34)));
Then I get the following message:
The field 'Stages_AssignedAgents_Id' is not indexed, cannot query on fields that are not indexed
Does anyone have any thoughts on where I have gone wrong here?
You index should be specified like so:
from job in docs.Jobs
select new
{
Stages_AssignedAgents_Id = job.Stages.SelectMany(x=>x.AssignedAgents).Select(x=>x.Id)
}
namespace WebApplication1.Site
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var accessToken = "" // Token
var client = new FacebookClient(accessToken);
dynamic myInfo = client.Get("me/friends", new { fields = "name,id,work" });
foreach (dynamic friend in myInfo)
{
foreach (dynamic work in friend.work ?? new[] { new { employer = new { name = string.Empty }, position = new { name = string.Empty } } })
{
Response.Write("Employer: " + work.employer.name);
}
}
}
}
}
I am getting the following error on line 21. I cannot figure out what is causing it.
'System.Collections.Generic.KeyValuePair' does not contain a definition for 'work'
Sample JSON Return from the Facebook GraphAPI. This is only the first three friends. There are closer to 4000 friends I am parsing, obviously this gives some context for the structure of the data:
{
"data": [
{
"name": "Mia xxx",
"id": "11381",
"work": [
{
"employer": {
"id": "100982923276720",
"name": "New-York Historical Society"
},
"location": {
"id": "108424279189115",
"name": "New York, New York"
}
}
]
},
{
"name": "Leilah xxx",
"id": "1133"
},
{
"name": "xxx,
"id": "1231",
"work": [
{
"employer": {
"id": "104362369673437",
"name": "Bye Bye Liver: The Philadelphia Drinking Play"
},
"location": {
"id": "101881036520836",
"name": "Philadelphia, Pennsylvania"
},
"position": {
"id": "121113421241569",
"name": "Actress/Bartender"
},
"description": "A sketch comedy/improv show every Saturday night at Downey's on South & Front. Come thirsty!",
"start_date": "2011-09"
},
{
"employer": {
"id": "100952634348",
"name": "Act II Playhouse"
},
"location": {
"id": "109249869093538",
"name": "Ambler, Pennsylvania"
},
"position": {
"id": "125578900846788",
"name": "My Fair Lady"
},
"description": "11 actor version of the classic musical.",
"start_date": "0000-00"
},
An alternative to relying on the dynamic is to capture and parse the JSON with JSON.net, it's designed for querying json data and is really much safer than using dynamic
http://json.codeplex.com/
And deserializing into classes:
http://dotnetbyexample.blogspot.ca/2012/02/json-deserialization-with-jsonnet-class.html
Look at this:
Response.Write("Employer: " + myInfo.work.employer.name);
I suspect you meant:
Response.Write("Employer: " + work.employer.name);
Put it this way - if that's not what you meant, what's the purpose of your work variable?