Ich bin neu im Umgang mit JSON-Daten.
Ich lese Daten von einem Webservice. Die zurückgesendeten Abfragedaten lauten wie folgt:
[["B02001_001E","NAME","state"],
["4712651","Alabama","01"],
["691189","Alaska","02"],
["6246816","Arizona","04"],
["18511620","Florida","12"],
["9468815","Georgia","13"],
["1333591","Hawaii","15"],
["1526797","Idaho","16"],
["3762322","Puerto Rico","72"]]
Gibt es eine Möglichkeit, diese Daten so zu deserialisieren, dass das Basisobjekt generiert wird, ohne dass ich zuerst definieren muss, wie das Objekt ist? Im obigen Beispiel wird das Objekt durch die erste Zeile definiert:
["B02001_001E","NAME","state"],
Im Allgemeinen gibt der Webdienst die als zweidimensionales JSON-Array formatierten Abfragedaten zurück, wobei die erste Zeile Spaltennamen und die nachfolgenden Zeilen Datenwerte enthalten.
Sie können dies sehr leicht deserialisieren. Die Datenstruktur in C # ist nur List<string[]>
, sodass Sie dies einfach tun können.
List<string[]> data = JsonConvert.DeserializeObject<List<string[]>>(jsonString);
Der obige Code setzt voraus, dass Sie json.NET verwenden.
BEARBEITEN: Beachten Sie, dass der Json technisch ein Array von String-Arrays ist. Ich bevorzuge List<string[]>
für meine eigene Deklaration, weil sie intuitiver ist. Es wird für json.NET keine Probleme verursachen. Wenn Sie ein Array von String-Arrays erstellen möchten, müssen Sie den Typ in (denke ich) string[][]
ändern, aber es gibt einige lustige kleine Gotchas mit gezackten und 2D-Arrays in C #. das weiß ich nicht wirklich, also kümmere ich mich hier nicht darum.
Wenn Sie .Net 4.5 verwenden, können Sie auch den standardmäßigen .Net-Json-Serialisierer verwenden:
using System.Runtime.Serialization.Json;
...
Stream jsonSource = ...; // serializer will read data stream
var s = new DataContractJsonSerializer(typeof(string[][]));
var j = (string[][])s.ReadObject(jsonSource);
In .NET 4.5 und älter können Sie die JavaScriptSerializer-Klasse verwenden:
using System.Web.Script.Serialization;
...
JavaScriptSerializer serializer = new JavaScriptSerializer();
string[][] list = serializer.Deserialize<string[][]>(json);
Schritt 1: Gehen Sie zu json.org, um die JSON-Bibliothek für die Technologie zu finden, die Sie zum Aufrufen dieses Webservice verwenden. Laden Sie die Bibliothek herunter und verlinken Sie sie.
Schritt 2: Angenommen, Sie verwenden Java. Sie würden JSONArray so verwenden:
JSONArray myArray=new JSONArray(queryResponse);
for (int i=0;i<myArray.length;i++){
JSONArray myInteriorArray=myArray.getJSONArray(i);
if (i==0) {
//this is the first one and is special because it holds the name of the query.
}else{
//do your stuff
String stateCode=myInteriorArray.getString(0);
String stateName=myInteriorArray.getString(1);
}
}
Sie können Ihren eigenen JSON-Parser schreiben und ihn je nach Anforderung generischer gestalten. Hier ist eine, die meinem Zweck gut gedient hat, die Hoffnung wird auch Ihnen helfen.
class JsonParsor
{
public static DataTable JsonParse(String rawJson)
{
DataTable dataTable = new DataTable();
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;
bool reading_number = false;
while (s >= 0)
{
s = bufferreader.Read();
//open JSON
if (!reading)
{
if ((char)s == '{' && !inside_string && !reading)
{
reading = true;
continue;
}
if ((char)s == '}' && !inside_string && !reading)
break;
if ((char)s == ']' && !inside_string && !reading)
continue;
if ((char)s == ',')
continue;
}
else
{
if (reading_value)
{
if (!inside_string && (char)s >= '0' && (char)s <= '9')
{
reading_number = true;
valuebufferbuilder.Append((char)s);
continue;
}
}
//if we find a quote and we are not yet inside a string, advance and get inside
if (!inside_string)
{
if ((char)s == '\"' && !inside_string)
inside_string = true;
if ((char)s == '[' && !inside_string)
{
keybufferbuilder.Length = 0;
valuebufferbuilder.Length = 0;
reading = false;
inside_string = false;
reading_value = false;
}
if ((char)s == ',' && !inside_string && reading_number)
{
if (!dataTable.Columns.Contains(keybufferbuilder.ToString()))
dataTable.Columns.Add(keybufferbuilder.ToString(), typeof(string));
if (!outdict.ContainsKey(keybufferbuilder.ToString()))
outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString());
keybufferbuilder.Length = 0;
valuebufferbuilder.Length = 0;
reading_value = false;
reading_number = false;
}
continue;
}
//if we reach end of the string
if (inside_string)
{
if ((char)s == '\"')
{
inside_string = false;
s = bufferreader.Read();
if ((char)s == ':')
{
reading_value = true;
continue;
}
if (reading_value && (char)s == ',')
{
//put the key-value pair into dictionary
if(!dataTable.Columns.Contains(keybufferbuilder.ToString()))
dataTable.Columns.Add(keybufferbuilder.ToString(),typeof(string));
if (!outdict.ContainsKey(keybufferbuilder.ToString()))
outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString());
keybufferbuilder.Length = 0;
valuebufferbuilder.Length = 0;
reading_value = false;
}
if (reading_value && (char)s == '}')
{
if (!dataTable.Columns.Contains(keybufferbuilder.ToString()))
dataTable.Columns.Add(keybufferbuilder.ToString(), typeof(string));
if (!outdict.ContainsKey(keybufferbuilder.ToString()))
outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString());
ICollection key = outdict.Keys;
DataRow newrow = dataTable.NewRow();
foreach (string k_loopVariable in key)
{
CommonModule.LogTheMessage(outdict[k_loopVariable],"","","");
newrow[k_loopVariable] = outdict[k_loopVariable];
}
dataTable.Rows.Add(newrow);
CommonModule.LogTheMessage(dataTable.Rows.Count.ToString(), "", "row_count", "");
outdict.Clear();
keybufferbuilder.Length=0;
valuebufferbuilder.Length=0;
reading_value = false;
reading = false;
continue;
}
}
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 dataTable;
}
}