I want to convert a XML to JSON. But due to the namespace,prefix and json array issues I am facing few issues.
Input XML
<notifications xmlns="http://soap.sforce.com/2005/09/outbound">
<OrganizationId>123</OrganizationId>
<ActionId>123</ActionId>
<SessionId xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<EnterpriseUrl>qwe</EnterpriseUrl>
<PartnerUrl>qwe</PartnerUrl>
<Notification>
<Id>123</Id>
<sObject xsi:type="sf:Opportunity" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
<sf:Id>ao123</sf:Id>
<sf:Amount>60000.0</sf:Amount>
<sf:CreatedDate>2014-11-26T14:45:52.000Z</sf:CreatedDate>
<sf:IsClosed>false</sf:IsClosed>
</sObject>
</Notification>
</notifications>
Output JSON
{
"notifications": {
"OrganizationId": "123",
"ActionId": "123",
"SessionId": {
"#nil": "true"
},
"EnterpriseUrl": "qwe",
"PartnerUrl": "qwe",
"Notification": [
{
"Id": "ao123",
"sObject": {
"#type": "sf:Opportunity",
"Id": "ao123",
"Amount": "60000.0",
"CreatedDate": "2014-11-26T14:45:52.000Z",
"IsClosed": "false"
}
}
]
}
}
So below are few issues which I am facing
Namespace and prefix of XML should not appear in json.
Notification should be a json array even if I receive one
item
So what I have tried so far is removing namespace and prefix using this method and then converting it to JSON using JsonConvert.SerializeXNode. Also to handle the array I can add json:Array="true" as mentioned here
I feel these steps are more of data manipulation and I am looking for some good approaches to achieve same. So I have tried using XSLT and I am able to remove the namespace prefix. fiddle link for XSLT. But I am not sure how to use XSLT to remove prefix and then convert my XML to my expected JSON format(may be using the XSLT xml-to-json options). Looking for a solution for this using XSLT
you can try try this code
var xDoc = XDocument.Parse(xmlString);
xDoc.Root.DescendantNodesAndSelf().OfType<XElement>().Attributes().Where(att => att.IsNamespaceDeclaration).Remove();
xDoc.Root.DescendantNodesAndSelf().OfType<XElement>().ToList().ForEach(node => node.Name = node.Name.LocalName);
var json = JsonConvert.SerializeXNode(xDoc, Newtonsoft.Json.Formatting.Indented, false);
or assuming https://xsltfiddle.liberty-development.net/aUPRNo/1 that after XSLT your xml is
<?xml version="1.0" encoding="UTF-8"?>
<notifications>
<OrganizationId>123</OrganizationId>
<ActionId>123</ActionId>
<SessionId nil="true" />
<EnterpriseUrl>qwe</EnterpriseUrl>
<PartnerUrl>qwe</PartnerUrl>
<Notification>
<Id>123</Id>
<sObject type="sf:Opportunity">
<Id>ao123</Id>
<Amount>60000.0</Amount>
<CreatedDate>2014-11-26T14:45:52.000Z</CreatedDate>
<IsClosed>false</IsClosed>
</sObject>
</Notification>
</notifications>
<notifications>
<OrganizationId>123</OrganizationId>
<ActionId>123</ActionId>
<SessionId nil="true" />
<EnterpriseUrl>qwe</EnterpriseUrl>
<PartnerUrl>qwe</PartnerUrl>
<Notification>
<Id>123</Id>
<sObject type="sf:Opportunity">
<Id>ao123</Id>
<Amount>60000.0</Amount>
<CreatedDate>2014-11-26T14:45:52.000Z</CreatedDate>
<IsClosed>false</IsClosed>
</sObject>
</Notification>
</notifications>
you can use this code to convert it to json
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
XmlNode node = xmlDoc.SelectSingleNode("notifications");
var json = JsonConvert.SerializeXmlNode(node, Newtonsoft.Json.Formatting.Indented, false);
in both cases the output is the same
{
"notifications": {
"OrganizationId": "123",
"ActionId": "123",
"SessionId": {
"#nil": "true"
},
"EnterpriseUrl": "qwe",
"PartnerUrl": "qwe",
"Notification": {
"Id": "123",
"sObject": {
"#type": "sf:Opportunity",
"Id": "ao123",
"Amount": "60000.0",
"CreatedDate": "2014-11-26T14:45:52.000Z",
"IsClosed": "false"
}
}
}
}
I am trying to create a JSON schema validator. My Json schema validates a certain property value and based on that it assigns value to another property. In my C# code I want to perform an action based on that. If you notice in my schema, if country is either "United States of America" or "Canada" then, I am setting effect be "compliant" else "non-complaint". And, In my C# code, I need the value of "effect" so that I can do some further processing. Is that possible? If not, what should be my approach? I am new to Json Schema (I have seen Azure polices doing something similar to this.)
Here is my Schema
{
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"country": {
"enum": [ "United States of America", "Canada" ]
},
"effect": {"type": "string"}
},
"if": {
"properties": { "country": { "const": "United States of America" } }
},
"then": {
"effect": "Compliant"
},
"else": {
"effect": "Non-Compliant"
}
}
Here is my Document
{
"properties": {
"street_address": "1600 Pennsylvania Avenue NW",
"country": "Canada",
"postal_code": "20500"
}
}
Here is my C# Code
JObject data = null;
var currentDirectory = Directory.GetParent(Environment.CurrentDirectory).Parent.Parent.FullName;
using (StreamReader r = new StreamReader(currentDirectory + #"/Documents/document.json"))
using (JsonTextReader reader = new JsonTextReader(r))
{
data = (JObject)JToken.ReadFrom(reader);
}
JsonSchema schema = JsonSchema.Parse(File.ReadAllText(currentDirectory + #"/Schemas/Schema.json"));
IList<string> messages;
var properties = (JObject)data["properties"];
bool valid = properties.IsValid(schema, out messages);
I am trying to create a method to send JSONRPC 2.0 commands using newtonsoft. I want to be able to pass parameters ant their values. Here is what I have so far
public void test(params object[] parameters)
{
JObject joe = new JObject();
joe.Add(new JProperty("jsonrpc", "2.0"));
joe.Add(new JProperty("id", "1"));
joe.Add(new JProperty("method", "Component.Set"));
JArray props = new JArray();
foreach (object parameter in parameters)
{
props.Add(parameter);
}
joe.Add(new JProperty("params", props));
string json = JsonConvert.SerializeObject(joe);
}
But my problem is that it only sends the parameter names, I don't know how to pass the values for the paramters
So basically, I am getting this
{
"jsonrpc": "2.0",
"id": "1",
"method": "Component.Set",
"params": [
"Name",
"GO"
]
}
when what I am looking for is something like this
{
"jsonrpc": "2.0",
"id": 1234,
"method": "Component.Set",
"params": {
"Name": "My APM",
"Controls": [
{
"Name": "ent.xfade.gain",
"Value": ‐100.0,
"Ramp": 2.0
}
]
}
}
How can I generate JSON with this format?
I have a problem;
I would to know if there is a method to parse json file without having a unique format. So it may have different attributes but all of them contain the attribute Status but it can be in double.
{
"requestid": "1111",
"message": "db",
"status": "OK",
"data": [
{
"Status": "OK", // this one I would to test first to read the other attributes
"fand": "",
"nalDate": "",
"price": 1230000,
"status": 2
}
]
}
With https://www.newtonsoft.com/json
Data data = JsonConvert.DeserializeObject<Data>(json);
And create the class Data with the interesting data inside the json
The defacto standard Json serializer for .NET is Newtonsoft.Json (How to install). You can parse the Json into an object graph and work on that in any order you like:
namespace ConsoleApp3
{
using System;
using Newtonsoft.Json.Linq;
class Program
{
static void Main()
{
var text = #"{
'requestid': '1111',
'message': 'db',
'status': 'OK',
'data': [
{
'Status': 'OK', // this one I would to test first to read the other attributes
'fand': '',
'nalDate': '',
'price': 1230000,
'status': 2
}
]
}";
var json = JObject.Parse(text);
Console.WriteLine(json.SelectToken("data[0].Status").Value<string>());
Console.ReadLine();
}
}
}
I am working on a Windows Phone 8.1 application involving location. I am receiving Json data from my API. My API returns data that looks like:
[{
"country": "India",
"city": "Mall Road, Gurgaon",
"area": "Haryana",
"PLZ": "122002",
"street": "",
"house_no": "",
"POI": "",
"type": "17",
"phone": "",
"lng": 77.08972334861755,
"lat": 28.47930118040612,
"formatted_address": "Mall Road, Gurgaon 122002, Haryana, India"
},
{
"country": "India",
"city": "Mall Road, Kanpur",
"area": "Uttar Pradesh",
"PLZ": "208004",
"street": "",
"house_no": "",
"POI": "",
"type": "17",
"phone": "",
"lng": 80.35783410072327,
"lat": 26.46026740300029,
"formatted_address": "Mall Road, Kanpur 208004, Uttar Pradesh, India"
},
{
"country": "India",
"city": "Mall Road Area, Amritsar",
"area": "Punjab",
"PLZ": "143001",
"street": "",
"house_no": "",
"POI": "",
"type": "17",
"phone": "",
"lng": 74.87286686897278,
"lat": 31.64115178002094,
"formatted_address": "Mall Road Area, Amritsar 143001, Punjab, India"
},
{
"country": "India",
"city": "Vasant Kunj (Mall Road Kishan Garh), New Delhi",
"area": "Delhi",
"PLZ": "110070",
"street": "",
"house_no": "",
"POI": "",
"type": "18",
"phone": "",
"lng": 77.1434211730957,
"lat": 28.51363217008815,
"formatted_address": "Vasant Kunj (Mall Road Kishan Garh), New Delhi 110070, Delhi, India"
}]
I am deserializing my Json data and putting it into a class named LocationData. When I run my code, it gives me an error:
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path
Where am I going wrong? Here is my code:
private async void GetAPIData()
{
string _serviceUrl = "https://api.myweblinkapiprovider/v2&q=" + UserRequestedLocation;
HttpClient client = new HttpClient();
HttpResponseMessage responce = await client.GetAsync(new Uri(_serviceUrl));
if (responce.Content != null)
{
var respArray = JObject.Parse(await responce.Content.ReadAsStringAsync());
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.NullValueHandling = NullValueHandling.Ignore;
settings.MissingMemberHandling = MissingMemberHandling.Ignore;
var rcvdData = JsonConvert.DeserializeObject<LocationData>(respArray.ToString(), settings);
UpdateMapData(rcvdData);
UpdateTextData(rcvdData);
}
}
I also tried to use a JArray. My code is as below:
private async void GetAPIData()
{
string _serviceUrl = "https://api.myweblinkprovider.com/v3?fun=geocode&lic_key=MyKey" + UserRequestedLocation;
HttpClient client = new HttpClient();
HttpResponseMessage responce = await client.GetAsync(new Uri(_serviceUrl));
JArray arr = JArray.Parse(await responce.Content.ReadAsStringAsync());
foreach (JObject obj in arr.Children<JObject>())
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.NullValueHandling = NullValueHandling.Ignore;
settings.MissingMemberHandling = MissingMemberHandling.Ignore;
var rcvdData = JsonConvert.DeserializeObject<LocationData>(arr.ToString(), settings);
UpdateMapData(rcvdData);
UpdateTextData(rcvdData);
}
}
It also gives me an error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'MMI_SpeechRecog.Model.LocationData' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
The first part of your question is a duplicate of Why do I get a JsonReaderException with this code?, but the most relevant part from that (my) answer is this:
[A] JObject isn't the elementary base type of everything in JSON.net, but JToken is. So even though you could say,
object i = new int[0];
in C#, you can't say,
JObject i = JObject.Parse("[0, 0, 0]");
in JSON.net.
What you want is JArray.Parse, which will accept the array you're passing it (denoted by the opening [ in your API response). This is what the "StartArray" in the error message is telling you.
As for what happened when you used JArray, you're using arr instead of obj:
var rcvdData = JsonConvert.DeserializeObject<LocationData>(arr /* <-- Here */.ToString(), settings);
Swap that, and I believe it should work.
Although I'd be tempted to deserialize arr directly as an IEnumerable<LocationData>, which would save some code and effort of looping through the array. If you aren't going to use the parsed version separately, it's best to avoid it.
In this case that you know that you have all items in the first place on array you can parse the string to JArray and then parse the first item using JObject.Parse
var jsonArrayString = #"
[
{
""country"": ""India"",
""city"": ""Mall Road, Gurgaon"",
},
{
""country"": ""India"",
""city"": ""Mall Road, Kanpur"",
}
]";
JArray jsonArray = JArray.Parse(jsonArrayString);
dynamic data = JObject.Parse(jsonArray[0].ToString());
I ran into a very similar problem with my Xamarin Windows Phone 8.1 app. The reason JObject.Parse(json) would not work for me was because my Json had a beginning "[" and an ending "]". In order to make it work, I had to remove those two characters. From your example, it looks like you might have the same issue.
jsonResult = jsonResult.TrimStart(new char[] { '[' }).TrimEnd(new char[] { ']' });
I was then able to use the JObject.Parse(jsonResult) and everything worked.
The following worked for me to convert a list of objects to json.
using Newtonsoft.Json;
static void Main(string[] args)
{
List<eventResponse> o = new List<eventResponse>()
{
new eventResponse { acknowledge = "test" } ,
new eventResponse { acknowledge = "test 2" }
};
var json = JsonConvert.SerializeObject(o);
JArray jo = JArray.Parse(json);
Console.WriteLine(jo);
}
public class eventResponse
{
public string acknowledge { get; set; }
}
A delayed answer but if you have access to the API you can work on the javascript object to make it as JSon. Something like
var jsonAddresses = { "addresses":
[
{
"country": "India",
"city": "Mall Road, Gurgaon",
},
{
"country": "India",
"city": "Mall Road, Kanpur",
}
]};
Then in C#
JObject Addjson = JObject.Parse(model.YourAddressesSampleJSONStr);