C # - تحليل البيانات سلمان مهيأ في hashtables متداخلة
سؤال
وأنا أحاول أن العمل مع بعض البيانات سلمان تنسيقها في C #، ولكن أواجه بعض المشاكل تحديد الطريقة المناسبة لمعالجة المشكلة. بلدي المسألة هي أن البيانات سلمان منسق ستكون في شكل غير معروف (وأنا أعرف أن يبدو غريبا ... يرجى قراءة). في الأساس، فإن البيانات سلمان مهيأ تكون بعض مجموعة من أزواج الاسم / القيمة حيث القيم قد تكون أو لا تكون صفائف من أزواج الاسم / القيمة المتداخلة. لجعل الأمور أكثر متعة، وتداخل صفائف زوج اسم / قيمة يمكن أن يستمر على ما لا نهاية.
وعلى سبيل المثال: وأنا قد يكون بعض البيانات التي تبدو وكأنها ...
{
"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 # التي من شأنها أن تمكنني من تحليل هذا بسهولة إلى مجموعة متداخلة من hastables؟
وأود أن تفعل شيئا على غرار (لاحظ هذا الرمز ليست صحيحة 100٪ نحويا وسيكون من الأفضل أن يتم ذلك عن طريق العودية ... لكنها تحصل هي الفكرة عبر).
Hashtable ht = [deserialize data method](jsonformattedstring);
foreach (Hashtable nested in ht)
{
If (nested.count > 1)
{
Foreach (hashtable next in nested)
…
}
}
المحلول
ولم يعجبني إعراب صافي سلمان ... يفعل بعض الاشياء الغريبة في بعض الأحيان. لقد تحولت إلى Json.NET ، مكتبة مفتوحة المصدر. أنه يحتوي على كائن JObject طيفة من شأنها أن تفعل ما تريد.
نصائح أخرى
في .NET، لديك في JsonArray ، والذي يسمح لك لتحميل وتحليل البيانات JSON. فإنه يخلق مجموعة من JsonValue وتماما المتداخلة يقوم على البيانات JSON أنه يوزع.
إذا كنت بحاجة إلى جدول هاش على وجه التحديد، هل يمكن ترجمة البيانات من JsonArray، على الرغم من Hastable هو كل شيء ولكن إهمال لصالح القاموس.
وقد جيدة جدا "بدء"وجوش هولمز بعد عن JSON في .NET: http://www.joshholmes.com/blog/2009/01/ 20 / PlayingWithJSON.aspx
وأنت قد ترغب في النظر في <لأ href = "http://techblog.procurios.nl/k/n618/news/view/14605/14863/How-do-I-write-my-own-parser- مقابل JSON.html "يختلط =" نوفولو "> http://techblog.procurios.nl/k/n618/news/view/14605/14863/How-do-I-write-my-own-parser-for- JSON.html ومن مكتبة البسيطة التي يوزع سلسلة JSON إلى Hashtables وArrayLists. ويمكن أيضا تحويل هذه الهياكل إلى JSON مرة أخرى.
وهنا هو طريقة كتبت في C # لتحليل JSON والعودة القاموس. بالطبع انها ليست مناسبة لجميع حالات الاستخدام، ولكن شيئا من هذا القبيل تعطيك لطيفة واحدة تمر تحليل للJSON:
/*
* 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;
}