軽量レベルのJSON変換コードを発表
24539 ワード
.NET FrameWork 2.0はJSON文字列オブジェクト化ツールを提供していないので、この変換器を書いてみましたが、現在使用中ですので、共有してください.実現方式は、正則+再帰である.変換が必要なJson文字列の複雑さには要求がない.テストを歓迎して、フィードバックを提供して、ありがとうございます.最初の運転は、少し遅く、初期化正則が時間を費やしたと推定され、これらの正則は静的であり、その後の変換は加速する.
ここでJsonNodeは解析結果を返す
NodeTypeは、現在のノードがどのようなタイプであるかを示す列挙タイプである.
IsArray: JsonNode.List
IsObject:JsonNode.DicObject
IsOriginal:JsonNode.Value
Json文字列の改行は、「aa\rbb」などの二重スラッシュでaaを表し、bbは隣接する2行である.
呼び出しコード:
/*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();