I want to parse the following JSON:
{"0":{"igloo_id":"0","name":"Igloo Removal","cost":"0"},"1":{"igloo_id":"1","name":"Basic Igloo","cost":"1500"},"2":{"igloo_id":"2","name":"Candy Igloo","cost":"1500"},"3":{"igloo_id":"3","name":"Deluxe Blue Igloo","cost":"4000"},"4":{"igloo_id":"4","name":"Big Candy Igloo","cost":"4000"},"5":{"igloo_id":"5","name":"Secret Stone Igloo","cost":"2000"},"6":{"igloo_id":"6","name":"Snow Igloo","cost":"1000"},"8":{"igloo_id":"8","name":"Secret Deluxe Stone Igloo","cost":"5000"},"9":{"igloo_id":"9","name":"Deluxe Snow Igloo","cost":"3000"},"10":{"igloo_id":"10","name":"Bamboo Hut","cost":"3200"},"11":{"igloo_id":"11","name":"Log Cabin","cost":"4100"},"12":{"igloo_id":"12","name":"Gym","cost":"4800"},"13":{"igloo_id":"13","name":"Split Level Igloo","cost":"4600"},"14":{"igloo_id":"14","name":"Candy Split Level Igloo","cost":"4600"},"15":{"igloo_id":"15","name":"Snowglobe","cost":"3700"},"16":{"igloo_id":"16","name":"Ice Castle","cost":"2400"},"17":{"igloo_id":"17","name":"Split Level Snow Igl","cost":"4600"},"18":{"igloo_id":"18","name":"Fish Bowl","cost":"2400"},"19":{"igloo_id":"19","name":"Tent","cost":"2700"},"20":{"igloo_id":"20","name":"Jack O' Lantern","cost":"2700"},"21":{"igloo_id":"21","name":"Backyard Igloo","cost":"4200"},"22":{"igloo_id":"22","name":"Pink Ice Palace","cost":"2400"},"23":{"igloo_id":"23","name":"Ship Igloo","cost":"4300"},"24":{"igloo_id":"24","name":"Dojo Igloo","cost":"1300"},"25":{"igloo_id":"25","name":"Gingerbread House","cost":"2100"},"26":{"igloo_id":"26","name":"Restaurant Igloo","cost":"4800"},"27":{"igloo_id":"27","name":"Tree House Igloo","cost":"4500"},"28":{"igloo_id":"28","name":"Theatre Igloo","cost":"4600"},"29":{"igloo_id":"29","name":"Circus Tent","cost":"0"},"30":{"igloo_id":"30","name":"Snowy Backyard Igloo","cost":"3000"},"31":{"igloo_id":"31","name":"Cave Igloo","cost":"1500"},"32":{"igloo_id":"32","name":"Green Clover Igloo","cost":"2050"},"33":{"igloo_id":"33","name":"Grey Ice Castle","cost":"2400"},"35":{"igloo_id":"35","name":"Cozy Cottage Igloo","cost":"2500"},"36":{"igloo_id":"36","name":"Estate Igloo","cost":"2500"},"37":{"igloo_id":"37","name":"In Half Igloo","cost":"2300"},"38":{"igloo_id":"38","name":"Shadowy Keep","cost":"2400"},"39":{"igloo_id":"39","name":"Dragon's Lair","cost":"3000"},"40":{"igloo_id":"40","name":"Mermaid Cove","cost":"3030"},"41":{"igloo_id":"41","name":"Whale's Mouth","cost":"2700"},"42":{"igloo_id":"42","name":"Trick-or-Treat Igloo","cost":"2000"},"43":{"igloo_id":"43","name":"Deluxe Gingerbread House","cost":"0"},"45":{"igloo_id":"45","name":"Invisible Snowy","cost":"0"},"46":{"igloo_id":"46","name":"Invisible Beach","cost":"0"},"47":{"igloo_id":"47","name":"Invisible Forest","cost":"0"},"48":{"igloo_id":"48","name":"Invisible Mountain","cost":"0"},"49":{"igloo_id":"49","name":"Shipwreck Igloo","cost":"900"},"50":{"igloo_id":"50","name":"Wildlife Den","cost":"900"},"51":{"igloo_id":"51","name":"Medieval Manor","cost":"1200"},"52":{"igloo_id":"52","name":"Warehouse","cost":"950"},"53":{"igloo_id":"53","name":"Pineapple Igloo","cost":"0"},"54":{"igloo_id":"54","name":"Creepy Cavern","cost":"1500"},"55":{"igloo_id":"55","name":"Frost Bite Palace","cost":"0"},"56":{"igloo_id":"56","name":"Fresh Baked Gingerbread House","cost":"2500"},"57":{"igloo_id":"57","name":"Penthouse","cost":"4000"},"58":{"igloo_id":"58","name":"VIP Penthouse","cost":"0"},"59":{"igloo_id":"59","name":"Invisible Age of Dinosaurs","cost":"0"},"60":{"igloo_id":"60","name":"Puffle Tree Fort","cost":"0"},"61":{"igloo_id":"61","name":"Secret Base","cost":"1600"},"62":{"igloo_id":"62","name":"Death Star Igloo","cost":"1000"},"63":{"igloo_id":"63","name":"Beach Party Igloo","cost":"1500"},"64":{"igloo_id":"64","name":"Gymnasium Igloo","cost":"0"},"65":{"igloo_id":"65","name":"Magical Hideout","cost":"1500"},"66":{"igloo_id":"66","name":"Eerie Castle","cost":"2000"},"67":{"igloo_id":"67","name":"Sweet Swirl Igloo","cost":"0"},"68":{"igloo_id":"68","name":"Train Station Igloo","cost":"1100"},"69":{"igloo_id":"69","name":"Main Event Igloo","cost":"1000"},"70":{"igloo_id":"70","name":"CP Airliner","cost":"1200"}}
I need a way to retrieve igloo_id, name and cost.
I've tried the following, but it's not what I want
List<Igloo> igloosList = JsonConvert.DeserializeObject<List<Igloo>>(itemJson);
This is the structure of my class
namespace Canvas
{
public class Igloo
{
public int cost;
public int igloo_id;
public string name;
public int Cost
{
get
{
return cost;
}
}
public int Id
{
get
{
return igloo_id;
}
}
public string Name
{
get
{
return name;
}
}
}
}
I'm not entirely sure I understand what you want. The code you posted generated an exception when I tried running it,
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List1[ConsoleApplication2.Program+Igloo]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
It did deserialize correctly if I used:
var igloosList = JsonConvert.DeserializeObject<Dictionary<string, Igloo>>( json );
If you want to loop through it you could then use:
foreach( var igloo in igloosList.Values )
Use the JsonProperty attribute :
[JsonProperty(PropertyName = "cost")]
public int Cost
{
get
{
return cost;
}
private set { cost = value; }
}
[JsonProperty(PropertyName = "igloo_id")]
public int Id
{
get
{
return igloo_id;
}
private set { igloo_id = value; }
}
[JsonProperty(PropertyName = "name")]
public string Name
{
get
{
return name;
}
private set { name = value; }
}
Basically you need to say for each property what is the Json key that will match. Plus, you will need to have a setter for each of your property, but it can be private.
I have a string with the following structure:
Student Name________AgeAddress_______________________Bithday___Lvl
Example:
Jonh Smith 016Some place in NY, USA 01/01/2014L01
As you can see, there is no delimited character like | or ,
Also, there is no space between fields (if you check, there is no space between Age/Address and Birthday/Level.
The size of each field is static so if data's length is less then it will contains white spaces.
I have a class that need to be filled with that information:
public class StudentData
{
public char[] _name = new char[20];
public string name;
public char[] _age = new char[3];
public string age;
public char[] _address = new char[30];
public string address;
public char[] _bday = new char[10];
public string bday;
public char[] _level = new char[3];
public string level;
}
Is there any way to do this automatically and dynamically?
I mean I really don't want to code like this:
myClass.name = stringLine.substring(0,19);
myClass.age = stringLine.substring(20,22);
That's because I have way more fields that the ones added in this example & way more string lines with other different data.
Update: There were supposed to be a lot of spaces between "Smith" and "016", but I don't know how to edit it.
Update2: If I use StringReader.Read() I can evade to use substring and indexes, but it isn't still so dynamically because I would need to repeat those 3 lines for each field.
StringReader reader = new StringReader(stringLine);
reader.Read(myClass._name, 0 myClass._name.Length);
myClass.name = new string(myClass._name);
Given your requirement I came up with an interesting solution. All be-it it may be more complex and longer than using the String.SubString() method as stated.
However this solution is transferable to other types and other string. I used a concept of Attributes, Properties, and Reflection to parse a string by a Fixed Length and setting the class Properties.
Note I did change your StudentData class to follow a more conventional coding style. Following this handy guide on MSDN: http://msdn.microsoft.com/en-us/library/xzf533w0(v=vs.71).aspx
Here is the new StudentData class. Note it uses the properties as opposed to fields. (Not discussed here).
public class StudentData
{
string name;
string age;
string address;
string bday;
string level;
[FixedLengthDelimeter(0, 20)]
public string Name { get { return this.name; } set { this.name = value; } }
[FixedLengthDelimeter(1, 3)]
public string Age { get { return this.age; } set { this.age = value; } }
[FixedLengthDelimeter(2, 30)]
public string Address { get { return this.address; } set { this.address = value; } }
[FixedLengthDelimeter(3, 10)]
public string BDay { get { return this.bday; } set { this.bday = value; } }
[FixedLengthDelimeter(4, 3)]
public string Level { get { return this.level; } set { this.level = value; } }
}
Note on each of the properties there is an Attribute called FixedLengthDelimeter that takes two parameters.
OrderNumber
FixedLength
The OrderNumber parameter denotes the order in the string (not the position) but the order in which we process from the string. The second parameter denotes the Length of the string when parsing the string. Here is the full attribute class.
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class FixedLengthDelimeterAttribute : Attribute
{
public FixedLengthDelimeterAttribute(int orderNumber, int fixedLength)
{
this.fixedLength = fixedLength;
this.orderNumber = orderNumber;
}
readonly int fixedLength;
readonly int orderNumber;
public int FixedLength { get { return this.fixedLength; } }
public int OrderNumber { get { return this.orderNumber; } }
}
Now the attribute is simple enough. Accepts the two paramters we discussed eariler in the constructor.
Finally there is another method to parse the string into the object type such as.
public static class FixedLengthFormatter
{
public static T ParseString<T>(string inputString)
{
Type tType = typeof(T);
var properties = tType.GetProperties(BindingFlags.Instance | BindingFlags.Public); //;.Where(x => x.GetCustomAttributes(typeof(FixedLengthDelimeterAttribute), false).Count() > 0);
T newT = (T)Activator.CreateInstance(tType);
Dictionary<PropertyInfo, FixedLengthDelimeterAttribute> dictionary = new Dictionary<PropertyInfo, FixedLengthDelimeterAttribute>();
foreach (var property in properties)
{
var atts = property.GetCustomAttributes(typeof(FixedLengthDelimeterAttribute), false);
if (atts.Length == 0)
continue;
dictionary[property] = atts[0] as FixedLengthDelimeterAttribute;
}
foreach (var kvp in dictionary.OrderBy(x => x.Value.OrderNumber))
{
int length = kvp.Value.FixedLength;
if (inputString.Length < length)
throw new Exception("error on attribute order number:" + kvp.Value.OrderNumber + " the string is too short.");
string piece = inputString.Substring(0, length);
inputString = inputString.Substring(length);
kvp.Key.SetValue(newT, piece.Trim(), null);
}
return newT;
}
}
The method above is what does the string parsing. It is a pretty basic utility that reads all the properties that have the FixedLengthDelimeter attribute applied a Dictionary. That dictionary is then enumerated (ordered by OrderNumber) and then calling the SubString() method twice on the input string.
The first substring is to parse the next Token while the second substring resets the inputString to start processing the next token.
Finally as it is parsing the string it is then applying the parsed string to the property of the class Type provided to the method.
Now this can be used simply like this:
string data1 = "Jonh Smith 016Some place in NY, USA 01/01/2014L01";
StudentData student = FixedLengthFormatter.ParseString<StudentData>(data1);
What this does:
Parses a string against property attributes in a fixed length format.
What this does not do:
It does convert the parsed strings to another type. Therefore all the properties must be a string. (this can be easily adapted by adding some type casting logic in).
It is not well tested. This is only tested against a few samples.
It is not by all means the only or best solution out there.
You could use FileHelpers library (NuGet).
Just define the structure of your input file with attributes:
[FixedLengthRecord]
public class StudentData
{
[FieldFixedLength(20)]
[FieldTrim(TrimMode.Right)]
public string name;
[FieldFixedLength(3)]
public string age;
[FieldFixedLength(30)]
[FieldTrim(TrimMode.Right)]
public string address;
[FieldFixedLength(10)]
public string bday;
[FieldFixedLength(3)]
public string level;
}
Then simply read the file using FileHelperEngine<T>:
var engine = new FileHelperEngine<StudentData>();
var students = engine.ReadFile(filename);
I am trying to use one web service which returns demanded data in json format. Now the actual point is I can fetch the data from the particular web service url in string.
string url= #"http://api.oodle.com/api/v2/listings?key=TEST®ion=chicago&category=vehicle&format=json";
string jsonString = new WebClient().DownloadString(url);
Now the point is I get the data in string (in JSON format). But I dont know how to convert the string into JSON string and how to fetch data from this string.
Let me give you example so you can easily understand
if my jsonString is like
{
"current":{
"region":{
"id":"chicago",
"name":"Chicago"
},
"category":{
"id":"vehicle",
"name":"Cars & Vehicles",
"abbrev":"Vehicles"
},
"start":1,
"num":10
}
}
How can i get region_name from that string ? Hope you understand me ! Try to use Test Link !
Add a reference to System.Web and then add to your using section
using System.Web.Script.Serialization;
Then (using your example json string)
string jsonString = "{\"current\":{\"region\":{\"id\":\"chicago\",\"name\":\"Chicago\"},\"category\":{\"id\":\"vehicle\",\"name\":\"Cars & Vehicles\",\"abbrev\":\"Vehicles\"},\"start\":1, \"num\":10}}";
JavaScriptSerializer serializer = new JavaScriptSerializer();
CurrentRecord currentRecord = serializer.Deserialize<CurrentRecord>(jsonString);
string regionName = currentRecord.current.region.name;
Also add the following classes to your project:
[Serializable]
public class CurrentRecord
{
public current current;
}
[Serializable]
public class current
{
public region region;
public category category;
public int start;
public int num;
}
[Serializable]
public class region
{
public string id;
public string name;
}
[Serializable]
public class category
{
public string id;
public string name;
public string abbrev;
}
Are you processing the JSON return string in Java, or JavaScript?
If you are processing the JSON response string in Java, you may make use of GSON. Here is a tutorial showing you how: Parsing a JSON String into an object with GSON easily.
For your case, you need a class like:
class Current{
private Region region;
private Category category;
private int start;
private int num;
// getters and setters
class Region{
private String id;
private String name;
// getters and setters
}
class Category{
private String id;
private String name;
private String abbreviation;
// getters and setters
}
}
Else if you are processing this JSON response String in Javascript, then you can have a look at this: http://www.json.org/js.html
alert(jsonReturnString.current.region.name);