C #- 구문 분석 JSON 형식 데이터는 중첩 된 해시블에 형식화
문제
C#에서 일부 JSON 형식의 데이터로 작업하려고하지만 문제에 접근하는 적절한 방법을 결정하는 데 문제가 있습니다. 내 문제는 JSON 형식의 데이터가 알려지지 않은 형식이라는 것입니다 (이상하게 들린다는 것을 알고 있습니다… 읽으십시오). 기본적으로 JSON 형식의 데이터는 값이 중첩 된 이름/값 쌍의 배열이거나 아닐 수도있는 이름/값 쌍의 일부 모음입니다. 일을 더 재미있게 만들기 위해 이름/값 쌍 어레이의 둥지는 Ad Infinitum에서 계속 될 수 있습니다.
예를 들어 : 나는 모양의 몇 가지 데이터가있을 수 있습니다…
{
"1": {
"1.1": {
"1.1.1": "value1",
"1.1.2": "value2",
"1.1.3": "value3"
},
"1.2": "value4",
"1.3": {
"1.3.1": {
"1.3.1.1": "value5",
"1.3.1.2": "value6"
},
"1.3.1.2": "value7",
"1.3.1.3": "value8"
}
}
}
불행히도, 나는 얼마나 많은 둥지가 일어날 지 모르고 기술적으로 주어진 메시지에 어떤 이름/가치 쌍이 존재하는지 모르겠습니다.
C#에는 이것을 중첩 된 공자 세트로 쉽게 구문 분석 할 수있는 지원 메커니즘이 있습니까?
나는 라인을 따라 무언가를하고 싶습니다 (이 코드는 100% 구문 적으로 정확하지 않으며 재귀를 통해 더 잘 수행 할 것입니다. 그러나 그것은 아이디어를 얻는 것입니다).
Hashtable ht = [deserialize data method](jsonformattedstring);
foreach (Hashtable nested in ht)
{
If (nested.count > 1)
{
Foreach (hashtable next in nested)
…
}
}
해결책
.NET JSON 구문 분석이 마음에 들지 않았습니다 ... 때때로 이상한 일을합니다. 나는 전환했다 json.net, 오픈 소스 라이브러리. 필요한 작업을 수행 할 수있는 좋은 작업 객체가 있습니다.
다른 팁
.NET에는 있습니다 JSONARRAY, JSON 데이터를로드하고 구문 분석 할 수 있습니다. JSONVALUE 배열을 생성하며 PARSE가 JSON 데이터를 기반으로 완전히 중첩됩니다.
구체적으로 Hashtable이 필요한 경우 JSONARRAY의 데이터를 번역 할 수 있지만, Hastable은 사전에 찬성하여 더 이상 사용되지 않습니다.
Josh Holmes는 .NET의 JSON에 대한 꽤 좋은 "Getting Start"게시물을 가지고 있습니다.http://www.joshholmes.com/blog/2009/01/20/playingwithjson.aspx
당신은보고 싶을 수도 있습니다 http://techblog.procurios.nl/k/k/n618/news/view/14605/14863/how-do-i-write-my-onparser-for-json.html JSON 문자열을 해시블 및 배열리스트로 구문 분석하는 간단한 라이브러리입니다. 또한이 구조를 다시 JSON으로 바꿀 수 있습니다.
다음은 C#에 JSON을 구문 분석하고 사전을 반환하기 위해 쓴 방법입니다. 물론 모든 사용 사례에 적합하지는 않지만 이와 같은 것은 JSON의 멋진 1 패스 구문 분석을 제공합니다.
/*
* 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;
}