使用Json.netparsingJSON

我试图parsing一些JSON使用JSon.Net库。 文件似乎有点稀疏,我很困惑如何完成我所需要的。 这是我需要parsing的JSON格式。

{ "displayFieldName" : "OBJECT_NAME", "fieldAliases" : { "OBJECT_NAME" : "OBJECT_NAME", "OBJECT_TYPE" : "OBJECT_TYPE" }, "positionType" : "point", "reference" : { "id" : 1111 }, "objects" : [ { "attributes" : { "OBJECT_NAME" : "test name", "OBJECT_TYPE" : "test type" }, "position" : { "x" : 5, "y" : 7 } } ] } 

我真正需要的唯一数据就是objects数组中的东西。 是否有可能通过像JSonTextReader这样的东西parsing,只是拔出我想要的东西,如OBJECT_TYPE和X和Y位置? 我似乎无法得到JSonTextReader以我想要的方式工作,我发现它的用法很less或没有例子。

看起来像序列化,然后使用LINQ与我的对象将是理想的,我发现每一个例子讨论序列化的JSON第一,但我不知道如何build立一个对象的结构。 特别是对象数组,这些对象数组需要类似于成对的属性和位置对象的列表。 我不知道如何编码我的对象,所以JSon.Net会知道如何序列化。

我以为我可以写我自己的简单的parsing器,只是把我需要的所有东西都放到我创build的属性对象中,但是我运气不大。

希望这一切都有道理,有什么想法?

我不知道JSON.NET,但它从System.Web.Extensions.dll (.NET 3.5 SP1)的JavaScriptSerializer工作正常:

 using System.Collections.Generic; using System.Web.Script.Serialization; public class NameTypePair { public string OBJECT_NAME { get; set; } public string OBJECT_TYPE { get; set; } } public enum PositionType { none, point } public class Ref { public int id { get; set; } } public class SubObject { public NameTypePair attributes { get; set; } public Position position { get; set; } } public class Position { public int x { get; set; } public int y { get; set; } } public class Foo { public Foo() { objects = new List<SubObject>(); } public string displayFieldName { get; set; } public NameTypePair fieldAliases { get; set; } public PositionType positionType { get; set; } public Ref reference { get; set; } public List<SubObject> objects { get; set; } } static class Program { const string json = @"{ ""displayFieldName"" : ""OBJECT_NAME"", ""fieldAliases"" : { ""OBJECT_NAME"" : ""OBJECT_NAME"", ""OBJECT_TYPE"" : ""OBJECT_TYPE"" }, ""positionType"" : ""point"", ""reference"" : { ""id"" : 1111 }, ""objects"" : [ { ""attributes"" : { ""OBJECT_NAME"" : ""test name"", ""OBJECT_TYPE"" : ""test type"" }, ""position"" : { ""x"" : 5, ""y"" : 7 } } ] }"; static void Main() { JavaScriptSerializer ser = new JavaScriptSerializer(); Foo foo = ser.Deserialize<Foo>(json); } } 

编辑:

Json.NET使用相同的JSON和类。

 Foo foo = JsonConvert.DeserializeObject<Foo>(json); 

链接: 用Json.NET序列化和反序列化JSON

编辑:谢谢马克,阅读结构与类问题,你是对的,谢谢!

我倾向于使用下面的方法来做你所描述的,使用JSon.Net的静态方法:

 MyObject deserializedObject = JsonConvert.DeserializeObject<MyObject>(json); 

链接: 用Json.NET序列化和反序列化JSON

对于对象列表,我可以build议使用由你自己的包含attributesposition类的小类生成的通用列表。 你可以在你的X和Y中使用System.DrawingSystem.Drawing.PointSystem.Drawing.PointF中的浮点数)中的Point结构。

在创build对象之后,获取您所查看的数据与您正在查看的文本parsing相比容易得多

 /* * This method takes in JSON in the form returned by javascript's * JSON.stringify(Object) and returns a string->string dictionary. * This method may be of use when the format of the json is unknown. * You can modify the delimiters, etc pretty easily in the source * (sorry I didn't abstract it--I have a very specific use). */ public static Dictionary<string, string> jsonParse(string rawjson) { Dictionary<string, string> outdict = new Dictionary<string, string>(); StringBuilder keybufferbuilder = new StringBuilder(); StringBuilder valuebufferbuilder = new StringBuilder(); StringReader bufferreader = new StringReader(rawjson); int s = 0; bool reading = false; bool inside_string = false; bool reading_value = false; //break at end (returns -1) while (s >= 0) { s = bufferreader.Read(); //opening of json if (!reading) { if ((char)s == '{' && !inside_string && !reading) reading = true; continue; } else { //if we find a quote and we are not yet inside a string, advance and get inside if (!inside_string) { //read past the quote if ((char)s == '\"') inside_string = true; continue; } if (inside_string) { //if we reached the end of the string if ((char)s == '\"') { inside_string = false; s = bufferreader.Read(); //advance pointer if ((char)s == ':') { reading_value = true; continue; } if (reading_value && (char)s == ',') { //we know we just ended the line, so put itin our dictionary if (!outdict.ContainsKey(keybufferbuilder.ToString())) outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString()); //and clear the buffers keybufferbuilder.Clear(); valuebufferbuilder.Clear(); reading_value = false; } if (reading_value && (char)s == '}') { //we know we just ended the line, so put itin our dictionary if (!outdict.ContainsKey(keybufferbuilder.ToString())) outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString()); //and clear the buffers keybufferbuilder.Clear(); valuebufferbuilder.Clear(); reading_value = false; reading = false; break; } } else { if (reading_value) { valuebufferbuilder.Append((char)s); continue; } else { keybufferbuilder.Append((char)s); continue; } } } else { switch ((char)s) { case ':': reading_value = true; break; default: if (reading_value) { valuebufferbuilder.Append((char)s); } else { keybufferbuilder.Append((char)s); } break; } } } } return outdict; } 

(这个问题在search引擎的search结果中很高,但是最后我用了一个不同的方法,在其他有类似问题的人阅读时加上这个老问题的答案)

你可以用Json.Net解决这个问题,并且做一个扩展方法来处理你想循环的项目:

 public static Tuple<string, int, int> ToTuple(this JToken token) { var type = token["attributes"]["OBJECT_TYPE"].ToString(); var x = token["position"]["x"].Value<int>(); var y = token["position"]["y"].Value<int>(); return new Tuple<string, int, int>(type, x, y); } 

然后像这样访问数据:(场景:写入控制台):

 var tuples = JObject.Parse(myJsonString)["objects"].Select(item => item.ToTuple()).ToList(); tuples.ForEach(t => Console.WriteLine("{0}: ({1},{2})", t.Item1, t.Item2, t.Item3)); 

您使用JSON类,然后调用GetData()函数。

 /// <summary> /// This class encodes and decodes JSON strings. /// Spec. details, see http://www.json.org/ /// /// JSON uses Arrays and Objects. These correspond here to the datatypes ArrayList and Hashtable. /// All numbers are parsed to doubles. /// </summary> using System; using System.Collections; using System.Globalization; using System.Text; public class JSON { public const int TOKEN_NONE = 0; public const int TOKEN_CURLY_OPEN = 1; public const int TOKEN_CURLY_CLOSE = 2; public const int TOKEN_SQUARED_OPEN = 3; public const int TOKEN_SQUARED_CLOSE = 4; public const int TOKEN_COLON = 5; public const int TOKEN_COMMA = 6; public const int TOKEN_STRING = 7; public const int TOKEN_NUMBER = 8; public const int TOKEN_TRUE = 9; public const int TOKEN_FALSE = 10; public const int TOKEN_NULL = 11; private const int BUILDER_CAPACITY = 2000; /// <summary> /// Parses the string json into a value /// </summary> /// <param name="json">A JSON string.</param> /// <returns>An ArrayList, a Hashtable, a double, a string, null, true, or false</returns> public static object JsonDecode(string json) { bool success = true; return JsonDecode(json, ref success); } /// <summary> /// Parses the string json into a value; and fills 'success' with the successfullness of the parse. /// </summary> /// <param name="json">A JSON string.</param> /// <param name="success">Successful parse?</param> /// <returns>An ArrayList, a Hashtable, a double, a string, null, true, or false</returns> public static object JsonDecode(string json, ref bool success) { success = true; if (json != null) { char[] charArray = json.ToCharArray(); int index = 0; object value = ParseValue(charArray, ref index, ref success); return value; } else { return null; } } /// <summary> /// Converts a Hashtable / ArrayList object into a JSON string /// </summary> /// <param name="json">A Hashtable / ArrayList</param> /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns> public static string JsonEncode(object json) { StringBuilder builder = new StringBuilder(BUILDER_CAPACITY); bool success = SerializeValue(json, builder); return (success ? builder.ToString() : null); } protected static Hashtable ParseObject(char[] json, ref int index, ref bool success) { Hashtable table = new Hashtable(); int token; // { NextToken(json, ref index); bool done = false; while (!done) { token = LookAhead(json, index); if (token == JSON.TOKEN_NONE) { success = false; return null; } else if (token == JSON.TOKEN_COMMA) { NextToken(json, ref index); } else if (token == JSON.TOKEN_CURLY_CLOSE) { NextToken(json, ref index); return table; } else { // name string name = ParseString(json, ref index, ref success); if (!success) { success = false; return null; } // : token = NextToken(json, ref index); if (token != JSON.TOKEN_COLON) { success = false; return null; } // value object value = ParseValue(json, ref index, ref success); if (!success) { success = false; return null; } table[name] = value; } } return table; } protected static ArrayList ParseArray(char[] json, ref int index, ref bool success) { ArrayList array = new ArrayList(); // [ NextToken(json, ref index); bool done = false; while (!done) { int token = LookAhead(json, index); if (token == JSON.TOKEN_NONE) { success = false; return null; } else if (token == JSON.TOKEN_COMMA) { NextToken(json, ref index); } else if (token == JSON.TOKEN_SQUARED_CLOSE) { NextToken(json, ref index); break; } else { object value = ParseValue(json, ref index, ref success); if (!success) { return null; } array.Add(value); } } return array; } protected static object ParseValue(char[] json, ref int index, ref bool success) { switch (LookAhead(json, index)) { case JSON.TOKEN_STRING: return ParseString(json, ref index, ref success); case JSON.TOKEN_NUMBER: return ParseNumber(json, ref index, ref success); case JSON.TOKEN_CURLY_OPEN: return ParseObject(json, ref index, ref success); case JSON.TOKEN_SQUARED_OPEN: return ParseArray(json, ref index, ref success); case JSON.TOKEN_TRUE: NextToken(json, ref index); return true; case JSON.TOKEN_FALSE: NextToken(json, ref index); return false; case JSON.TOKEN_NULL: NextToken(json, ref index); return null; case JSON.TOKEN_NONE: break; } success = false; return null; } protected static string ParseString(char[] json, ref int index, ref bool success) { StringBuilder s = new StringBuilder(BUILDER_CAPACITY); char c; EatWhitespace(json, ref index); // " c = json[index++]; bool complete = false; while (!complete) { if (index == json.Length) { break; } c = json[index++]; if (c == '"') { complete = true; break; } else if (c == '\\') { if (index == json.Length) { break; } c = json[index++]; if (c == '"') { s.Append('"'); } else if (c == '\\') { s.Append('\\'); } else if (c == '/') { s.Append('/'); } else if (c == 'b') { s.Append('\b'); } else if (c == 'f') { s.Append('\f'); } else if (c == 'n') { s.Append('\n'); } else if (c == 'r') { s.Append('\r'); } else if (c == 't') { s.Append('\t'); } else if (c == 'u') { int remainingLength = json.Length - index; if (remainingLength >= 4) { // parse the 32 bit hex into an integer codepoint uint codePoint; if (!(success = UInt32.TryParse(new string(json, index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codePoint))) { return ""; } // convert the integer codepoint to a unicode char and add to string s.Append(Char.ConvertFromUtf32((int)codePoint)); // skip 4 chars index += 4; } else { break; } } } else { s.Append(c); } } if (!complete) { success = false; return null; } return s.ToString(); } protected static double ParseNumber(char[] json, ref int index, ref bool success) { EatWhitespace(json, ref index); int lastIndex = GetLastIndexOfNumber(json, index); int charLength = (lastIndex - index) + 1; double number; success = Double.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); index = lastIndex + 1; return number; } protected static int GetLastIndexOfNumber(char[] json, int index) { int lastIndex; for (lastIndex = index; lastIndex < json.Length; lastIndex++) { if ("0123456789+-.eE".IndexOf(json[lastIndex]) == -1) { break; } } return lastIndex - 1; } protected static void EatWhitespace(char[] json, ref int index) { for (; index < json.Length; index++) { if (" \t\n\r".IndexOf(json[index]) == -1) { break; } } } protected static int LookAhead(char[] json, int index) { int saveIndex = index; return NextToken(json, ref saveIndex); } protected static int NextToken(char[] json, ref int index) { EatWhitespace(json, ref index); if (index == json.Length) { return JSON.TOKEN_NONE; } char c = json[index]; index++; switch (c) { case '{': return JSON.TOKEN_CURLY_OPEN; case '}': return JSON.TOKEN_CURLY_CLOSE; case '[': return JSON.TOKEN_SQUARED_OPEN; case ']': return JSON.TOKEN_SQUARED_CLOSE; case ',': return JSON.TOKEN_COMMA; case '"': return JSON.TOKEN_STRING; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': return JSON.TOKEN_NUMBER; case ':': return JSON.TOKEN_COLON; } index--; int remainingLength = json.Length - index; // false if (remainingLength >= 5) { if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e') { index += 5; return JSON.TOKEN_FALSE; } } // true if (remainingLength >= 4) { if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') { index += 4; return JSON.TOKEN_TRUE; } } // null if (remainingLength >= 4) { if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') { index += 4; return JSON.TOKEN_NULL; } } return JSON.TOKEN_NONE; } protected static bool SerializeValue(object value, StringBuilder builder) { bool success = true; if (value is string) { success = SerializeString((string)value, builder); } else if (value is Hashtable) { success = SerializeObject((Hashtable)value, builder); } else if (value is ArrayList) { success = SerializeArray((ArrayList)value, builder); } else if ((value is Boolean) && ((Boolean)value == true)) { builder.Append("true"); } else if ((value is Boolean) && ((Boolean)value == false)) { builder.Append("false"); } else if (value is ValueType) { // thanks to ritchie for pointing out ValueType to me success = SerializeNumber(Convert.ToDouble(value), builder); } else if (value == null) { builder.Append("null"); } else { success = false; } return success; } protected static bool SerializeObject(Hashtable anObject, StringBuilder builder) { builder.Append("{"); IDictionaryEnumerator e = anObject.GetEnumerator(); bool first = true; while (e.MoveNext()) { string key = e.Key.ToString(); object value = e.Value; if (!first) { builder.Append(", "); } SerializeString(key, builder); builder.Append(":"); if (!SerializeValue(value, builder)) { return false; } first = false; } builder.Append("}"); return true; } protected static bool SerializeArray(ArrayList anArray, StringBuilder builder) { builder.Append("["); bool first = true; for (int i = 0; i < anArray.Count; i++) { object value = anArray[i]; if (!first) { builder.Append(", "); } if (!SerializeValue(value, builder)) { return false; } first = false; } builder.Append("]"); return true; } protected static bool SerializeString(string aString, StringBuilder builder) { builder.Append("\""); char[] charArray = aString.ToCharArray(); for (int i = 0; i < charArray.Length; i++) { char c = charArray[i]; if (c == '"') { builder.Append("\\\""); } else if (c == '\\') { builder.Append("\\\\"); } else if (c == '\b') { builder.Append("\\b"); } else if (c == '\f') { builder.Append("\\f"); } else if (c == '\n') { builder.Append("\\n"); } else if (c == '\r') { builder.Append("\\r"); } else if (c == '\t') { builder.Append("\\t"); } else { int codepoint = Convert.ToInt32(c); if ((codepoint >= 32) && (codepoint <= 126)) { builder.Append(c); } else { builder.Append("\\u" + Convert.ToString(codepoint, 16).PadLeft(4, '0')); } } } builder.Append("\""); return true; } protected static bool SerializeNumber(double number, StringBuilder builder) { builder.Append(Convert.ToString(number, CultureInfo.InvariantCulture)); return true; } } //parse and show entire json in key-value pair Hashtable HTList = (Hashtable)JSON.JsonDecode("completejsonstring"); public void GetData(Hashtable HT) { IDictionaryEnumerator ienum = HT.GetEnumerator(); while (ienum.MoveNext()) { if (ienum.Value is ArrayList) { ArrayList arnew = (ArrayList)ienum.Value; foreach (object obj in arnew) { Hashtable hstemp = (Hashtable)obj; GetData(hstemp); } } else { Console.WriteLine(ienum.Key + "=" + ienum.Value); } } }