Entwickler-Ecke

ASP.NET und Web - Umwandlung einer Json-Datei in mehrere mit Sortierung


billy01 - Di 06.09.16 17:21
Titel: Umwandlung einer Json-Datei in mehrere mit Sortierung
Hallo,

ich bin neu hier und hoffe, die Kategorie ist richtig.

Mein Problem:
Ich wandle einen Vertretungsplan in json um:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
[
  {
    "Klasse": "05A",
    "Datum": "6.8.",
    "Art": "Freisetzung",
    "Fach": "---",
    "Vertreter": "---",
    "Stunde": "1",
    "Raum": "---",
    "Vertretungstext": "---"
  },
  {
    "Klasse": "05D",
    "Datum": "6.8.",
    "Art": "Freisetzung",
    "Fach": "---",
    "Vertreter": "---",
    "Stunde": "1 - 2",
    "Raum": "---",
    "Vertretungstext": "---"
  },
  {
    "Klasse": "05B",
    "Datum": "6.8.",
    "Art": "Freisetzung",
    "Fach": "---",
    "Vertreter": "---",
    "Stunde": "1 - 2",
    "Raum": "---",
    "Vertretungstext": "---"
  },
  {
    "Klasse": "05C",
    "Datum": "6.8.",
    "Art": "Freisetzung",
    "Fach": "---",
    "Vertreter": "---",
    "Stunde": "1 - 2",
    "Raum": "---",
    "Vertretungstext": "---"
  },
  {
    "Klasse": "06A",
    "Datum": "6.8.",
    "Art": "Sondereins.",
    "Fach": "VFG",
    "Vertreter": "R�dM",
    "Stunde": "1 - 2",
    "Raum": "n114",
    "Vertretungstext": "---"
  }]

Nun brauche ich aber noch für jede Klasse Einzeldateien. Also für jede Klasse für ein bestimmtes Datum eine Datei (sie sollte dann klasse-datum.json heissen, nur so kann unser Infosystem damit umgehen).

Momentan benutze ich json.net für die erste Umwandlung, vielleicht geht das ja damit auch.

Vielen Dank für eure Vorschläge und Ideen,

Billy.

Moderiert von user profile iconTh69: Code-Tags hinzugefügt


Palladin007 - Di 06.09.16 17:48

json.net kann json in Objekte deserialisieren und umgekehrt?

Dann deserialisiere doch die komplette json-Datei, sortiere/filtere die Objekte wie Du sie brauchst (LINQ to Objects ist da klasse) und serialisiere die einzelnen Listen dann in eigene Dateien.

Anders wirds wohl kaum gehen und wenn json.net dafür schon Funktionen anbieten sollte, wird's das genauso machen.


Ralf Jansen - Di 06.09.16 18:02

Wo stehst du denn jetzt genau mit Json.Net.

Hast du konkrete Typen(Klassen) in deiner Anwendung entsprechend dem gezeigten Json oder benutzt du nur die generischen Klassen von Json.Net (JObject, JArray etc. also Ableitngen von JToken)?
Was heist genau Einzeldatei. Eine Untermenge des jetzigen Json im identischen Format oder sind die anders?


billy01 - Di 06.09.16 18:12

Hallo Ralf,

ich habe alle Elemente hier:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
class Temp_Felder
{
    public string Klasse { get; set; }
    public string Datum { get; set; }
    public string Art { get; set; }
    public string Fach { get; set; }
    public string Vertreter { get; set; }
    public string Stunde { get; set; }
    public string Raum { get; set; }
    public string Vertretungstext { get; set; }
}


Mit Einzeldatei meine ich, für jedes Datum mit Klasse eine Datei. Da sind dann alle Stunden und so weiter aus dem Temp-File drin. Eigentlich müssen nur alle "Blöcke" mit einer Klasse zu einem Datum rausgesucht werden, nach der Stunde sortiert werden und in die Datei geschrieben werden. Dann muss diese mit klasse-datum (etwa 05a-6-8.json) benannt werden. Dann gehts weiter mit der nächsten Klasse, solange bis alle durch sind.

Grüsse,

Billy.

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Moderiert von user profile iconTh69: Full-Quote entfernt.


Ralf Jansen - Di 06.09.16 18:22

Ich wiederhole in meinen Worten um abzugleichen ob ich das verstanden habe.

1. im Quell-Json gibt es beliebige Kombinationen aus Datum und Klasse(n) (jeweils eine Instanz der Klasse Temp_Felder, da gibt es doch bestimmt einen besseren Namen die Bezeichner sind so schon schön konkret das ein generischer Name unpassend wirkt)
2. für jede dieser Kombination soll eine neue Datei entstehen. Die alle Daten dieser Klasse an diesem Datum zusammenfast.
3. Das Format dieser neuen Json Dateien ist aber identisch zum Quell-Json besteht aber halt nur aus einer Untermenge dieser?


billy01 - Di 06.09.16 18:28

Jawoll. Eine Klassen-Datei sieht dann so aus:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
[
  "detail",
  {
    "Klasse": "05A",
    "Datum": "6.8.",
    "Art": "Freisetzung",
    "Fach": "---",
    "Vertreter": "---",
    "Stunde": "1",
    "Raum": "---",
    "Vertretungstext": ""
  },
  {
    "Klasse": "05A",
    "Datum": "6.8.",
    "Art": "Freisetzung",
    "Fach": "---",
    "Vertreter": "---",
    "Stunde": "2",
    "Raum": "---",
    "Vertretungstext": ""
  }]

Dateiname: 05A-6-8.json

Moderiert von user profile iconTh69: Code-Tags hinzugefügt
Moderiert von user profile iconTh69: Full-Quote entfernt.


Th69 - Di 06.09.16 18:37

Hallo billy01 :welcome:

ich habe jetzt ersteinmal deine Beiträge editiert und die Code bzw. C#-Tags gesetzt sowie die Vollzitate entfernt.
Bitte halte dich bei deinen zukünftigen Beiträgen selber daran.


Ralf Jansen - Di 06.09.16 19:28

Dann etwa so.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
string sourcePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string pathToSourceFile = Path.Combine(sourcePath, "source.json");  // Pfad zum Quell Json hier beispielhaft am Ort der Anwendung mit Namen source.json

var list = JsonConvert.DeserializeObject<List<Temp_Felder>>(File.ReadAllText(pathToSourceFile));

var groupedList = from item in list group item by new { item.Klasse, item.Datum };

foreach (var groupeditem in groupedList)
{
    string filename = Path.Combine(sourcePath, $"{groupeditem.Key.Klasse}-{groupeditem.Key.Datum}.json");  // Ausgabedateiname in den gleichen Ordner, hier einfach Datum nehmen ist vermutlich zu einfach da Punkte im Datum 
    File.WriteAllText(filename, JsonConvert.SerializeObject(groupeditem.ToList(), Formatting.Indented));
}


billy01 - Mi 07.09.16 21:14

Hallo Ralf,

danke! Dein Code funktioniert super!

Eine Sache noch: wäre es möglich, vom Datum das letzte Zeichen zu löschen? Die Mutter-JSON enthält das Datum mit einem Bindestrich am Ende, vielleicht kann man den noch entfernen.

Vielen Dank,

Billy.


Ralf Jansen - Mi 07.09.16 22:04

Klar. Strings haben eine Remove Methode. Alternativ kannst du das auch per TrimEnd oder SubString Methode machen. Alles da bei strings um etwas zu entfernen/auszuschneiden.


billy01 - Mi 07.09.16 22:26

Das hier: ... $"{groupeditem.Key.Klasse}-{groupeditem.Key.Datum.Remove(groupeditem.Key.Datum, -1)}");

Gibt mir aber einen Fehler... Wie komme ich denn an den String mit dem Datum ran?


Ralf Jansen - Mi 07.09.16 22:49

Doku lesen?

Die 2 Parameter von Remove sind Startindex und Anzahl Zeichen. Ist groupeditem.Key.Datum eine Position in einem string (eine Zahl)? Kann eine negative Zahl eine gültige Anzahl Zeichen sein bbei der Aufgabe lösche ab Stelle x bitte y Zeichen?


billy01 - Do 08.09.16 13:40

Hallo Ralf,

ich hab`s geschafft. Danke !