Huhu,
ich nutze Newtonsoft.Json um den content der customfields aus folgendem Object zu ermitteln:
total "2"
issues
0
id "1"
fields
customfield_1 "one"
customfield_2
value: "one"
id: "1"
1
id "2"
fields
customfield_1 "two"
customfield_2
value: "two"
id: "2"
Es fehlt jedoch eine Möglichkeit verschachtelte Schlüssel auf Existenz abzufragen. Z.B. so
Object.ContainsKey("total"));
Die Klasse JObject bietet die Möglichkeit nur für Schlüssel in erster Ebene. JToken scheinbar gar nicht. Meine Codevariante funktioniert leider nicht.
if (jObject["issues"] != null)
{
foreach (JToken issue in jObject["issues"])
{
if (issue["fields"] != null)
{
foreach (string customfield in myCustomfields)
{
if (issue["fields"][customfield] != null)
{
if (issue["fields"][customfield]["id"] != null)
{
//get content
}
if (issue["fields"][customfield]["value"] != null)
{
//get content
}
}
}
}
}
}
Bliebe noch die Möglichkeit mit String Operationen drauf los zugehen ... weiß jemand, ob es auch eleganter funktioniert?
Danke Euch
Achso: Das tatsächliche Object ist recht groß und ich brauche nur sehr wenig vom Inhalt. Ich hatte auf performante Boardmittel von JSON gehofft um gezielt zu navigieren
Ich hatte auf performante Boardmittel von JSON gehofft um gezielt zu navigieren
Wenn es dir wirklich um Performance und Speicherauslastung geht, musst Du umdenken.
Sobald Du frei navigieren können willst, wird es langsam, stattdessen musst Du Token für Token lesen und je nach Situation entscheiden, wie Du damit umgehst.
Das hat natürlich den Nachteil, dass der Code komplexer wird. Dein Code-Snippet funktioniert so nicht mehr, stattdessen brauchst Du Schleifen, die so lange überspringen (oder hinein springen), bis sie dort gelandet sind, wo Du hin willst.
Für XML gibt's da den XmlReader, damit hab ich mal das Lesen von einem 600MB-XML deutlich beschleunigt, ein ehemaliger Kollege hatte Spaß mit einem 10GB-XML (kein Witz)
In Newtonsoft.Json scheint dafür die JsonTextReader-Klasse gedacht zu sein, selber genutzt habe ich sie aber noch nicht.
Und dann gibt's noch System.Text.Json, das wurde von Microsoft entwickelt, um eine möglichst performante Möglichkeit zu bieten, JSON zu lesen.
Ob das wirklich so gut ist, weiß ich nicht, ich hab's nur anfangs mal ausprobiert und für einfache Fälle konnte es (damals) noch nicht bei Newtonsoft.Json mithalten. Wie das heute aussieht, musst Du ausprobieren.
By the way:
Von welcher Größenordnung reden wir hier?
Klingt vernünftig. Die Varianten schau ich mir mal an. 300MB sollte die Grenze sein - da wäre noch viel Luft zu deinem Wert. Danke
Meine Codevariante funktioniert leider nicht.
Wenn du beim nächsten Mal schreibst, was nicht funktioniert, kann man dir auch dabei helfen, den Fehler zu finden. "Funktioniert nicht" ist keine Fehlerbeschreibung, mit der irgendjemand etwas anfangen kann.
Siehe [Hinweis] Wie poste ich richtig?, besonders Punkt 5
Weeks of programming can save you hours of planning
Klingt eigentlich nach dem falschen Ansatz.
Wenn dies gültiges Json ist, müsstest du im einfachsten Fall nur eine Klasse anlegen, die den aufbau des Json Objekt hat.
Dann kannst du das Json zu einer Instanz der Klasse deserialisieren.
Dann kannst du direkt mit der Klasse arbeiten.
Wenn du aktuell mit 300 MB Json arbeitest, sollten da weit unter 100 MB RAM für die Instanz nötig sein.
Dann musst du dich auch nicht mit dem durcharbeiten des Json kümmern.
Du musst dann nur die innere Liste eines Objekts durchlaufen und die entsprechenden Einträge ermitteln.
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
300 MB Json zu serialisieren um auf ein paar Felder zuzugreifen ist dämlich ja aber du kannst doch einfach auf das Feld direkt zugreifen
using System;
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main()
{
var json = @"{
""total"": 1,
""issues"": {
""id"": 1,
""fields"": {
""field1"": 1,
""field2"": 2
}
}
}";
JObject data = JObject.Parse(json);
Console.WriteLine("Total: " + data["total"]);
}
}
Willst du wissen ob das feld existiert dann prüfe einfach auf null
if (data["existiertnicht"] != null) oder eben ContainsKey
wenn es dir um den Joken in deiner umständlcihen beschreibung geht dann kannst du auch da einfach auf null prüfen.
JObjekt ist unter der Haube ein Dictionary (IDictionary<string, JToken) daher gibt es hier ein Contains und beim JToken eben nicht