How to remove parent element from json in c# - c#

How to covert the below json
{"data":{"id":12,"name":"jeremy","email":"jeremy#test.com"}}
to
{"id":12,"name":"jeremy","email":"jeremy#test.com"}
I want to remove the "data" element from json.

With json.net it's fairly straightforward
var input = "{\"data\":{\"id\":12,\"name\":\"jeremy\",\"email\":\"jeremy#test.com\"}}";
var result = JObject.Parse(input)["data"].ToString(Formatting.None);
Console.WriteLine(result);
Note : Formatting.None is only to preserve the formatting you had in your original example
Or Text.Json
var result = JsonDocument.Parse(input).RootElement.GetProperty("data").ToString();
Output
{"id":12,"name":"jeremy","email":"jeremy#test.com"}
Additional Resources
JObject.Parse Method (String)
Load a JObject from a string that contains JSON.
JObject.Item Property (String)
Gets or sets the JToken with the specified property name.
JToken.ToString Method (Formatting,JsonConverter[])
Returns the JSON for this token using the given formatting and
converters.
Formatting Enumeration
None 0 No special formatting is applied.
Text.Json
JsonDocument.Parse Method
Provides a mechanism for examining the structural content of a JSON
value without automatically instantiating data values.
JsonDocument.RootElement Property
Gets the root element of this JSON document
JsonElement.GetProperty Method
Gets a JsonElement representing the value of a required property
identified by propertyName.

I have a follow up question on a scenario where I don't want to remove the root element.
{
"keepMe": {
"removeMe": [
{
"id": "1",
"name": "Foo",
"email": "Foo#email.com"
},
{
"id": "2",
"name": "Bar",
"email": "Bar#email.com"
}
]
}
But I wanted it to look like
{
"keepMe": {
{
"id": "1",
"name": "Foo",
"email": "Foo#email.com"
},
{
"id": "2",
"name": "Bar",
"email": "Bar#email.com"
}
}
Using below would not work. Is there another way to do this?
var result = JObject.Parse(input)["keepMe"]["removeMe"].ToString(Formatting.None);
//{
// "id": "1",
// "name": "Foo",
// "email": "Foo#email.com"
//},
//{
// "id": "2",
// "name": "Bar",
// "email": "Bar#email.com"
//}
var result = JObject.Parse(input)["removeMe"].ToString(Formatting.None); //Null Reference
Found the answer using the SelectToken and Replace keyword
var jObj = JObject.Parse(input);
jObj.SelectToken("keepMe").Replace(jObj.SelectToken("keepMe.removeMe"));
string result = jObj.ToString();

Related

How to get a particular value from Json using SelectToken

I have a JSON like this
{
"Customer": {
"$type": "Dictionary`2",
"Id": "6448DE37E2F3D9588118A1950"
},
"Databases": [
{
"$type": "Pime",
"Id": 1,
"Name": "Peter",
"MobNo": 78877629,
"PAN": "SAKKJKJ",
"Defaulter": true,
},
{
"$type": "Pime",
"Id": 2,
"Name": "James",
"MobNo": 58277699,
"PAN": "NAQKJKJ",
"Defaulter": false,
},
{
"$type": "Pime",
"Id": 3,
"Name": "Norton",
"MobNo": 38877699,
"PAN": "TAKKJKJ",
"Defaulter": true,
},
]
}
I'm using a token to select the node and return the customer information whose Id=2
My code goes like this:
StreamReader r = new StreamReader("C:\TestJson\Test.db");
string json = r.ReadToEnd();
JObject o = JObject.Parse(json);
JToken result = o.SelectToken("$.Databases[?(#.Id == '2')]");
But I am getting the result as null. Am I using the wrong token in the SelectToken() method?
First of all given JSON is invalid, in database array value of Name and PAN keys should be of type string. You are missing "(double qoutes) in above json.
Second and most important thing, type of Id is an integer and in your Json Path you are trying to search with string type i.e '2', try to search Id by integer without quoute it will work.
//No single qoutes for 2.
JToken result = o.SelectToken("$.Databases[?(#.Id == 2)]");

How to access inner properties of a Json Object?

I am learning C# and I am trying to parse json/xml responses and check each and every key and value pair. For xml I am converting to json so I have only one function/script to work with both cases. My issue is that I am working with a wide range of json responses which are not similar and there may be arrays in some of the json response. I have tried accessing the "Count" of the json object as a way to check for arrays.
Note: The responses will vary. This example is for Products > Product > name, quantity and category. The next response will change and can be like Country > State > Cities and so on. I cannot rely on creating classes since all responses are going to be different. Plus I am working on automating it so it should be able to handle anything thrown at it.
Sample Json I am working with:
{
"products": {
"product": [
{
"name": "Dom quixote de La Mancha",
"quantity": "12",
"category": "Book"
},
{
"name": "Hamlet",
"quantity": "3",
"category": "Book"
},
{
"name": "War and Peace",
"quantity": "7",
"category": "Book"
},
{
"name": "Moby Dick",
"quantity": "14",
"category": "Book"
},
{
"name": "Forrest Gump",
"quantity": "16",
"category": "DVD"
}
]
}
The way I am accessing the count, name and value is as follows:
dynamic dyn = JsonConvert.DeserializeObject<dynamic>(jsonText);
foreach (JProperty property in dyn.Properties())
{
string propname = property.Name;
var propvalue = property.Value;
int count = property.Count;
}
Is there a way to access these without going through the foreach loop like int count = dyn.Count ? All I am getting from this is null instead of actual values.
For the above example my end result will be like:
This responses contains products> product> 5 x (name, quantity, category)
The QuickWatch for the object:
QuickWatch for dyn object
Try to deserialize your JSON into JObject like below:
var jObject = JsonConvert.DeserializeObject<JObject>(jsonText);

How to get sys_id from the result(incident_response) from below c# code

I have the following JSON(modified) which is read from a HttpWebRequest response stream, and I want to extract the value of "sys_id":
{
"result": {
"number": "INC0012618",
"opened_by": {
"link": "//XXX.service-now.com/api/now/v1/table/sys_user/38723e5ddb42f200deb8f6fcbf96196d",
"value": "38723e5ddb42f200deb8f6fcbf96196d"
},
"sys_created_on": "2017-07-20 14:41:52",
"sys_domain": {
"link": "://XXX.service-now.com/api/now/v1/table/sys_user_group/global",
"value": "global"
},
"u_incident_summary": "",
"business_service": {
"link": "://xxx.service-now.com/api/now/v1/table/cmdb_ci_service/IT services",
"value": "IT services"
},
"work_end": "",
"caller_id": {
"link": "://xxxx.service-now.com/api/now/v1/table/sys_user/71f5455d4f735e000d7f0ed11310c719",
"value": "71f5455d4f735e000d7f0ed11310c719"
},
"close_code": "",
"assignment_group": {
"link": "://xxx.service-now.com/api/now/v1/table/sys_user_group/9e158987dba27a007ea0f4e9bf961983",
"value": "9e158987dba27a007ea0f4e9bf961983"
},
"sys_id": "7fb4e50edb8c0b007ea0f4e9bf9619ba",
"u_outage_start_time": ""
}
}
This is what I have tried so far, where incident_responce is a string containing the JSON above:
var jObject = JObject.Parse(incident_responce);
var value = (string)jObject["sys_id"];
Console.WriteLine(value);
But, it didn't work, I think because there is "result" at the start. How can I retrieve this value?
As you suspected, your initial attempt fails because "sys_id" is nested inside the "result" object:
{ "result": { ... "sys_id":"7fb4e50edb8c0b007ea0f4e9bf9619ba" } }
It's easier to see this if you indent and format your JSON, for instance by uploading it to https://jsonformatter.curiousconcept.com/.
Such a nested value can be queried directly by using JToken.SelectToken():
var root = JToken.Parse(incident_responce);
var value = (string)root.SelectToken("result.sys_id");
SelectToken() supports querying for values deep within the JSON container hierarchy using JSONPath syntax. If the "result.sys_id" token is not found, null is returned.
Alternatively, you could use Json.NET's support for querying JSON hierarchies using dynamic functionality:
dynamic root = JToken.Parse(incident_responce);
var value = (string)root.result.sys_id;
However, if the "result" token is not found, a RuntimeBinderException will be thrown instead of a null value returned.
Working .Net fiddle.

How can I use a JSONPath expression as a filter inside another JSONPath expression?

I want to select objects from a JSON string by filtering using a JSONPath expression with another expression embedded in the filter. In other words, I want to filter for a value that is present elsewhere in the JSON data.
For example:
In the following JSON data there is a value in $.Item.State.stepId (currently "QG2.0"). I need to have a JSONPath expression that selects values based on this value, like this:
$..Step[?(#.stepId==$Item.State.stepId)].actionDate
But this will not return any results. If I use the string ("QG2.0") directly like this:
$..Step[?(#.stepId=='QG2.0')].actionDate
it will return the required data.
What's wrong, or is it not even possible? My JSON is below:
{
"Item": {
"Common": {
"folio": "PSH-000016020",
"setName": "123-XZ200-1",
"wfId": "Kat1_002",
"wfIssue": "002",
"wfIdIssue": "Kat1_002.002"
},
"State": {
"status": "IN WORK",
"stepId": "QG2.0",
"stepDescription": "Validation"
},
"Participants": {
"Participant": [
{
"role": "PR",
"roleDescription": "Product Responsible",
"loginName": "marc102",
"email": "mark#abc.de"
}, {
"role": "CR",
"roleDescription": "Chapter Responsible",
"loginName": "uli26819",
"email": "uli#abc.de"
}
]
},
"Steps": {
"Step": [
{
"stepId": "QG1.0",
"stepTitle": "Preparation",
"actionDate": "2016-06-28T10:28:09",
"actionDueDate": "",
"actionBy_Name": "Marc",
"actionBy_Account": "marc102",
"action": "complete",
"Comment": ""
}, {
"stepId": "QG2.0",
"stepTitle": "Check Requirements",
"actionDate": "2016-08-08T14:17:04",
"actionDueDate": "",
"actionBy_Name": "Uli",
"actionBy_Account": "uli26819",
"action": "complete",
"Comment": ""
}
]
}
}
}
I don't think Json.Net's implementation of JSONPath supports this concept.
However, you can still get the information you want if you break the query into two steps:
JObject obj = JObject.Parse(json);
JToken stepId = obj.SelectToken("Item.State.stepId");
JToken actionDate = obj.SelectToken(string.Format("$..Step[?(#.stepId=='{0}')].actionDate", stepId));
Console.WriteLine(actionDate.ToString());
Fiddle: https://dotnetfiddle.net/KunYTf

JSON.NET reader problem

i got some problem when i generate .json file from spring .json ,and i got this format
{ "models": [
{
"id":1,
"modelName":"dfdsf",
"created":{
"userFullname":"demo",
"time":"150301",
"date":"20110208",
"userId":"123"
},
"remark":"dsfdf",
"updated":"~unique-id~1"
},
{
"id":2,
"modelName":"test",
"created":{
"userFullname":"test",
"time":"150301",
"date":"20110210",
"userId":"124"
},
"remark":"test",
"updated":{
"userFullname":"test",
"time":"150301",
"date":"20110209",
"userId":"test"
}
}
]}
first time i used JObject Parse for convert
JObject job = JObject.Parse(fullJson);
and the other hand i used jtoken to focus "models"
JToken jDetail = job["models"];
but the problem is {[{ xxx }]} it look like jarray i don't have any idea to convert it
i ever use JArray, JsonTextReader but it doesn't work.
could suggestion some? because if i pass this ll i set some value to object.
thank you for every idea.
string fullJson = File.ReadAllText("TextFile1.txt"); // for brevity
var job = JObject.Parse(fullJson);
var models = job.Value<JArray>("models");
Console.WriteLine(models[0]);
result:
{
"id": 1,
"modelName": "dfdsf",
"created": {
"userFullname": "demo",
"time": "150301",
"date": "20110208",
"userId": "123"
},
"remark": "dsfdf",
"updated": "~unique-id~1"
}

Categories