Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Wie kann ich mehrdimensionales JSON auf Key-Existenz überprüfen?
Exception234
myCSharp.de - Member



Dabei seit:
Beiträge: 11

Themenstarter:

Wie kann ich mehrdimensionales JSON auf Key-Existenz überprüfen?

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
HansFred
myCSharp.de - Member



Dabei seit:
Beiträge: 49

beantworten | zitieren | melden

Warum serialisierst du nicht einfach das Objekt?
private Nachricht | Beiträge des Benutzers
Exception234
myCSharp.de - Member



Dabei seit:
Beiträge: 11

Themenstarter:

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Member

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1413
Herkunft: NRW

beantworten | zitieren | melden

Zitat
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?
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Palladin007 am .
private Nachricht | Beiträge des Benutzers
Exception234
myCSharp.de - Member



Dabei seit:
Beiträge: 11

Themenstarter:

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5960
Herkunft: Leipzig

beantworten | zitieren | melden

Zitat von Exception234
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
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1768
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
HansFred
myCSharp.de - Member



Dabei seit:
Beiträge: 49

beantworten | zitieren | melden

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
https://dotnetfiddle.net/ZGyAWR
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von HansFred am .
private Nachricht | Beiträge des Benutzers