軽量レベルのJSON変換コードを発表

24539 ワード

.NET FrameWork 2.0はJSON文字列オブジェクト化ツールを提供していないので、この変換器を書いてみましたが、現在使用中ですので、共有してください.実現方式は、正則+再帰である.変換が必要なJson文字列の複雑さには要求がない.テストを歓迎して、フィードバックを提供して、ありがとうございます.最初の運転は、少し遅く、初期化正則が時間を費やしたと推定され、これらの正則は静的であり、その後の変換は加速する.
/*create by ayymbirst @gmail.com */
using
System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; namespace JsonConver { /// <summary> /// /// </summary> public enum NodeType { /// <summary> /// /// </summary> IsArray , /// <summary> /// /// </summary> IsObject , /// <summary> /// /// </summary> IsOriginal , /// <summary> /// /// </summary> Undefined } // Json public class JsonNode { public NodeType NodeType; public List<JsonNode> List; public Dictionary<string, JsonNode> DicObject; public string Value; } /// <summary> /// json /// </summary> public class ConvertJsonObject { static string regTxt = "({0}[^{0}{1}]*(((?'Open'{0})[^{0}{1}]*)+((?'-Open'{1})[^{0}{1}]*)+)*(?(Open)(?!)){1})"; // ( ) static string regKeyValue = "({0}.{1}?(?<!\\\\){0})"; // , // ( , ) static string regOriginalValue = string.Format("({0}|{1}|{2})", string.Format(regKeyValue, "'", "*"), string.Format(regKeyValue, "\"", "*"), "\\w+"); // value ( ) static string regValue = string.Format("({0}|{1}|{2})", regOriginalValue // , string.Format(regTxt, "\\[", "\\]"), string.Format(regTxt, "\\{", "\\}")); // static string regKeyValuePair = string.Format("\\s*(?<key>{0}|{1}|{2})\\s*:\\s*(?<value>{3})\\s*" , string.Format(regKeyValue, "'", "+"), string.Format(regKeyValue, "\"", "+"), "([^ :,]+)" // key , regValue); // value /// <summary> /// /// </summary> static Regex RegJsonStrack1 = new Regex(string.Format("^\\{0}(({2})(,(?=({2})))?)+\\{1}$", "{", "}", regKeyValuePair), RegexOptions.Compiled); /// <summary> /// /// </summary> static Regex RegJsonStrack2 = new Regex(string.Format("^\\[(({0})(,(?=({0})))?)+\\]$", regValue), RegexOptions.Compiled); /// <summary> /// /// </summary> static Regex RegJsonStrack3 = new Regex(regKeyValuePair, RegexOptions.Compiled); // value static Regex RegJsonStrack4 = new Regex(regValue, RegexOptions.Compiled); // static Regex RegJsonStrack6 = new Regex(string.Format("^{0}$", regOriginalValue), RegexOptions.Compiled); // [] , {} static Regex RegJsonRemoveBlank = new Regex("(^\\s*[\\[\\{'\"]\\s*)|(\\s*[\\]\\}'\"]\\s*$)", RegexOptions.Compiled); string JsonTxt; public ConvertJsonObject(string json) { // json = Regex.Replace(json, "[\r
]
", ""); JsonTxt = json; } /// <summary> /// /// </summary> /// <param name="json"></param> /// <returns></returns> public NodeType MeasureType(string json) { if (RegJsonStrack1.IsMatch(json)) { return NodeType.IsObject; } if (RegJsonStrack2.IsMatch(json)) { return NodeType.IsArray; } if (RegJsonStrack6.IsMatch(json)) { return NodeType.IsOriginal; } return NodeType.Undefined; } /// <summary> /// json /// </summary> /// <param name="json"></param> /// <returns></returns> public JsonNode SerializationJsonNodeToObject() { return SerializationJsonNodeToObject(JsonTxt); } /// <summary> /// json /// </summary> /// <param name="json"></param> /// <returns></returns> public JsonNode SerializationJsonNodeToObject(string json) { json = json.Trim(); NodeType nodetype = MeasureType(json); if (nodetype == NodeType.Undefined) { throw new Exception(" Json: " + json); } JsonNode newNode = new JsonNode(); newNode.NodeType = nodetype; if (nodetype == NodeType.IsArray) { json = RegJsonRemoveBlank.Replace(json, ""); MatchCollection matches = RegJsonStrack4.Matches(json); newNode.List = new List<JsonNode>(); foreach (Match match in matches) { if (match.Success) { newNode.List.Add(SerializationJsonNodeToObject(match.Value)); } } } else if (nodetype == NodeType.IsObject) { json = RegJsonRemoveBlank.Replace(json, ""); MatchCollection matches = RegJsonStrack3.Matches(json); newNode.DicObject = new Dictionary<string, JsonNode>(); string key; foreach (Match match in matches) { if (match.Success) { key = RegJsonRemoveBlank.Replace(match.Groups["key"].Value, ""); if (newNode.DicObject.ContainsKey(key)) { throw new Exception("json , json:" + json); } newNode.DicObject.Add(key, SerializationJsonNodeToObject(match.Groups["value"].Value)); } } } else if (nodetype == NodeType.IsOriginal) {  newNode.Value = RegJsonRemoveBlank.Replace(json, "").Replace("\\r\
", "\r
");
} return newNode; } } }

ここでJsonNodeは解析結果を返す
NodeTypeは、現在のノードがどのようなタイプであるかを示す列挙タイプである.
IsArray: JsonNode.List
IsObject:JsonNode.DicObject
IsOriginal:JsonNode.Value
Json文字列の改行は、「aa\rbb」などの二重スラッシュでaaを表し、bbは隣接する2行である.
 
呼び出しコード:
JsonConver.ConvertJsonObject jsonObj = new JsonConver.ConvertJsonObject("{'a':11,'b':[1,2,3],'c':{'a':1,'b':[1,2,3]}}");

            JsonConver.JsonNode node = jsonObj.SerializationJsonNodeToObject();

            if (node.NodeType == JsonConver.NodeType.IsObject)

            {

                if (node.DicObject["a"].NodeType == JsonConver.NodeType.IsOriginal)

                {

                    Console.Write("key:a , value:");

                    Console.Write(node.DicObject["a"].Value);

                    Console.WriteLine();

                }



                if (node.DicObject["b"].NodeType == JsonConver.NodeType.IsArray)

                {

                    Console.Write("key:b,value for first:");

                    Console.Write(node.DicObject["b"].List[0].Value);

                    Console.WriteLine();

                }



                if (node.DicObject["c"].NodeType == JsonConver.NodeType.IsObject)

                {

                    if (node.DicObject["c"].DicObject["a"].NodeType == JsonConver.NodeType.IsOriginal)

                    {

                        Console.Write("key:c      : , value:");

                        Console.Write(node.DicObject["c"].DicObject["a"].Value);

                        Console.WriteLine();

                    }

                }

            }



       



                Console.Read();