Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   .NET-Sprachen (https://www.delphipraxis.net/82-net-sprachen/)
-   -   C# JSON Parsen (https://www.delphipraxis.net/188575-json-parsen.html)

franktron 17. Mär 2016 09:48

JSON Parsen
 
Ich habe ein Problem mit C# MVC, ich muss ein JSON Parsen der nicht immer gleich ist.

1. Zustand "[[\"Bezeichnung\",\"=\",\"2K-Gelcoat-PUR-Steodur-3kg\"]]"
2. Zustand "[[[\"Bezeichnung\",\"=\",\"2K-Gelcoat-PUR-Steodur-3kg\"]],\"and\",[[\"charge\",\"=\",\"11\"]]]"

WIe kann ich das machen für Zustand 1 habe ich volgenden Code
Code:
JavaScriptSerializer serializer = new JavaScriptSerializer();
            List<string[]> filterItems = serializer.Deserialize<List<string[]>>(filter);

            string buffer = "";

            foreach (string[] filterItem in filterItems)
            {
               buffer = buffer + filterItem[0] + " " + filterItem[1] + " " + filterItem[2];
               //list = FilterItems<YourItemType>(list, filterItem[0], filterItem[2]);
            }

Sir Rufo 17. Mär 2016 10:02

AW: JSON Parsen
 
Sei doch so lieb und zeige uns den puren JSON-Code (eingebettet in die CODE-Tags). Bei diesem String aus dem Debugger mit den Escape-Zeichen sieht man ja den Wald vor lauter Bäumen nicht.

Ich wette, dann wird dich auch schon die Lösung anspringen :stupid:

franktron 17. Mär 2016 10:21

AW: JSON Parsen
 
Sorry habs einfach aus dem Debug rasukopiert


1. [["Bezeichnung","=","Angussstutzen-Rev/B-PPTV30"]]
2. [[["Bezeichnung","=","Angussstutzen-Rev/B-PPTV30"]],"and",[["charge","=","11"]]]

Sir Rufo 17. Mär 2016 12:59

AW: JSON Parsen
 
  1. Variante
    Code:
    [
       [
          "Bezeichnung",
          "=",
          "Angussstutzen-Rev/B-PPTV30"
       ]
    ]
  2. Variante
    Code:
    [
       [
          [
             "Bezeichnung",
             "=",
             "Angussstutzen-Rev/B-PPTV30"
          ]
       ],
       "and",
       [
          [
             "charge",
             "=",
             "11"
          ]
       ]
    ]
Schauen wir uns an, was wir da haben (wir fangen von aussen an):
  • Hat das äußere Array einen Eintrag, dann haben wir die Variante 1 vor uns
  • Hat das äußere Array drei Einträge, dann haben wir die Variante 2 vor uns, wobei das Item 0 und Item 2 wie die Variante 1 behandelt werden kann

himitsu 17. Mär 2016 13:38

AW: JSON Parsen
 
Es ist eigentlich immer nur eine Variante. (im aktuellen Beispiel)
Delphi-Quellcode:
[WertA, Operator, WertB]
Code:
Auswertgung:
[
   "Bezeichnung",       Spalte
   "=",                 Vergleichsoperator
   "Angussstutzen..."   Wert
]

Verknüpfung
[
   [ VergleichA ],      GruppeA
   "and",               Operator
   [ VergleichB ]       GruppeB
]

interessant wären jetzt mehrere Verknüpfungen ... eventuell so, oder immer nur in 2er-Gruppen
[
   [ VergleichA ],      GruppeA
   "and",               Operator
   [ VergleichB ]       GruppeB
   "and",               Operator
   [ VergleichC ]       GruppeC
]

[
   [ VergleichA ],      GruppeA
   "and",               Operator
   [
      [ VergleichB ]    GruppeB.A
      "and",            Operator
      [ VergleichC ]    GruppeB.B
   ]
]

Sir Rufo 17. Mär 2016 14:09

AW: JSON Parsen
 
Wenn ich die eckigen Klammern zähle, dann sehe ich das etwas anders

himitsu 17. Mär 2016 14:30

AW: JSON Parsen
 
Lege zwei "Auswertgung" in ein "Verknüpfung" rein und schon kommt das doch mit den Klammern doch hin?

Sir Rufo 17. Mär 2016 14:43

AW: JSON Parsen
 
Zitat:

Zitat von himitsu (Beitrag 1333185)
Lege zwei "Auswertgung" in ein "Verknüpfung" rein und schon kommt das doch mit den Klammern doch hin?

Es gibt aber auch den Fall, wo es nur einen Vergleich gibt. Diesen Fall muss man speziell behandeln, alle anderen (mehrere Vergleiche verknüpft mit einem Operator) folgen durchaus dem, was du gezeigt hast.

Die Frage dreht sich hier aber ganz speziell um die Erkennung dieser beiden Fälle

Sir Rufo 17. Mär 2016 15:19

AW: JSON Parsen
 
Mal eben so heruntergetippt ...
Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.Json,
  System.SysUtils;

function IsEven( const Value: Integer ): Boolean;
begin
  Result := Value mod 2 = 0;
end;

function ParseSingleExpression( AJsonArray: TJsonArray ): string;
var
  lInner   : TJsonArray;
  lFieldName: string;
  lOperator : string;
  lValue   : string;
begin
  if AJsonArray.Count <> 1
  then
    raise EArgumentException.Create( 'single item in array expected' );

  if not( AJsonArray.Items[ 0 ] is TJsonArray )
  then
    raise EArgumentException.Create( 'array expected' );

  lInner := AJsonArray.Items[ 0 ] as TJsonArray;

  if lInner.Count <> 3
  then
    raise EArgumentException.Create( 'three items expected' );

  if not( lInner.Items[ 0 ] is TJSONString )
  then
    raise EArgumentException.Create( 'string expected' );
  lFieldName := lInner.Items[ 0 ].Value;

  if not( lInner.Items[ 1 ] is TJSONString )
  then
    raise EArgumentException.Create( 'string expected' );
  lOperator := lInner.Items[ 1 ].Value;

  if lInner.Items[ 2 ] is TJSONString
  then
    lValue := QuotedStr( lInner.Items[ 2 ].Value )
  else
    lValue := lInner.Items[ 2 ].Value;

  Result := string.Format( '(%s %s %s)', [ lFieldName, lOperator, lValue ] );
end;

function ParseJsonExpression( AJsonArray: TJsonArray ): string;
overload
var
  I: Integer;
begin
  if IsEven( AJsonArray.Count )
  then
    raise EArgumentException.Create( 'odd items in array expected' );

  if AJsonArray.Count = 1
  then
    Result := ParseSingleExpression( AJsonArray )
  else
    begin
      Result := '( ';
      for I := 0 to AJsonArray.Count - 1 do
        begin
          if I mod 2 = 0
          then
            if AJsonArray.Items[ I ] is TJsonArray
            then
              Result := Result + ParseJsonExpression( AJsonArray.Items[ I ] as TJsonArray )
            else
              raise EArgumentException.Create( 'Array expected' )
          else
            Result := Result + ' ' + AJsonArray.Items[ I ].Value + ' ';
        end;
      Result := Result + ' )';
    end;
end;

function ParseJsonExpression( AJsonStr: string ): string; overload;
var
  lValue: TJSONValue;
begin
  lValue := TJSONObject.ParseJSONValue( AJsonStr );
  try
    if lValue is TJsonArray
    then
      Result := ParseJsonExpression( lValue as TJsonArray )
    else
      raise EArgumentException.Create( 'Fehlermeldung' );
  finally
    lValue.Free;
  end;
end;

const
  Data1 = '[["Bezeichnung","=","Angussstutzen-Rev/B-PPTV30"]]';
  Data2 = '[[["Bezeichnung","=","Angussstutzen-Rev/B-PPTV30"]],"and",[["charge","=","11"]]]';
  Data3 = '[[["Bezeichnung","=","Angussstutzen-Rev/B-PPTV30"]],"and",[["charge","=","11"]],"and",[[["Bezeichnung","=","Angussstutzen-Rev/B-PPTV30"]],"and",[["charge","=","11"]]]]';

procedure Main;
begin
  WriteLn( Data1 );
  WriteLn( ParseJsonExpression( Data1 ) );
  WriteLn;
  WriteLn( Data2 );
  WriteLn( ParseJsonExpression( Data2 ) );
  WriteLn;
  WriteLn( Data3 );
  WriteLn( ParseJsonExpression( Data3 ) );
end;

begin
  try
    Main( );
  except
    on E: Exception do
      WriteLn( E.ClassName, ': ', E.Message );
  end;
  ReadLn;

end.
und liefert
Code:
[["Bezeichnung","=","Angussstutzen-Rev/B-PPTV30"]]
(Bezeichnung = 'Angussstutzen-Rev/B-PPTV30')

[[["Bezeichnung","=","Angussstutzen-Rev/B-PPTV30"]],"and",[["charge","=","11"]]]
( (Bezeichnung = 'Angussstutzen-Rev/B-PPTV30') and (charge = '11') )

[[["Bezeichnung","=","Angussstutzen-Rev/B-PPTV30"]],"and",[["charge","=","11"]],"and",[[["Bezeichnung","=","Angussstutzen-Rev/B-PPTV30"]],"and",[["charge","=","11"]]]]
( (Bezeichnung = 'Angussstutzen-Rev/B-PPTV30') and (charge = '11') and ( (Bezeichnung = 'Angussstutzen-Rev/B-PPTV30') and (charge = '11') ) )

Sherlock 18. Mär 2016 10:17

AW: JSON Parsen
 
Sorry4OT: So viel zum Thema "JSON ist sooo einfach" :D XML hat halt etwas mehr overhead, aber einfacher als JSON ist es allemal.

Sherlock

franktron 18. Mär 2016 10:21

AW: JSON Parsen
 
Zitat:

Zitat von Sherlock (Beitrag 1333262)
Sorry4OT: So viel zum Thema "JSON ist sooo einfach" :D XML hat halt etwas mehr overhead, aber einfacher als JSON ist es allemal.

Sherlock

Ja aber mit Javascript ist nun mal alles JSON.

Ich habe es jetzt gelöst etwas Krank aber es geht,
ich habe den String in ein Array zerlegt.

Valle 18. Mär 2016 10:29

AW: JSON Parsen
 
Zitat:

Zitat von Sherlock (Beitrag 1333262)
So viel zum Thema "JSON ist sooo einfach" :D XML hat halt etwas mehr overhead, aber einfacher als JSON ist es allemal.

Tut mir leid, aber da muss ich dir etwas OT widersprechen.

Wenn diese spezielle Syntax nicht so aufgebläht wäre und man die zu Verfügung stehenden Datentypen benutzen würde, wäre JSON deutlich einfacher. Hier sind allerdings unnötig verschachtelte Klammern und es werden nur Arrays statt Objekte verwendet. Ein tolles Beispiel für ziemlich schlechte Verwendung von JSON.

Mein Vorschlag für Variante 2 aus #4:

Code:
{
    "left": {
       "left": "Bezeichnung",
       "op": "=",
       "right": "Angussstutzen-Rev/B-PPTV30"
    },
    "op": "and",
    "right": {
        "left": "charge",
        "op": "=",
        "right": "11"
    }
}
Vorteile:
  • Keine unnötige Verschachtelung
  • Dank Objects keine ungültige Syntax möglich (z.B. "A, =, B, C")
  • Einfach lesbar und rekursiv zu verarbeiten
  • Klare und logische Verwendung von Datentypen
    • Objekte sind Ausdrücke
    • Strings entsprechen je nach Kontext Bezeichnern, Werten oder Operationen

p80286 19. Mär 2016 09:40

AW: JSON Parsen
 
Zitat:

Zitat von Sherlock (Beitrag 1333262)
Sorry4OT: So viel zum Thema "JSON ist sooo einfach" :D XML hat halt etwas mehr overhead, aber einfacher als JSON ist es allemal.

Sherlock

Nunja wenn ich mir die XML-Sourcen anschaue, die bei Windows mitgeliefert werden, kräuseln sich mir die Fußnägel. Ich mußte einen ganzen Satz von abhängigen Parametern (u.a. SQL-Sourcen Array of record ...) ablegen. Das ging mit JSON wesentlich eleganter als mit XML. Wobei die Lesbarkeit der verschiedenen Sourcen nicht für JSON spricht.

Gruß
K-H

Phoenix 19. Mär 2016 14:57

AW: JSON Parsen
 
Laut dem Titel geht es hier um C#.
Und da gibts mit Newtonsoft.JSON ein Library das das komplett übernimmt.

man schmeisst das Json da nur rein und bekommt ein deserialisiertes Objekt zurück mit dem man weiter arbeiten kann.

madas 20. Mär 2016 13:21

AW: JSON Parsen
 
Zitat:

Zitat von Phoenix (Beitrag 1333359)
Laut dem Titel geht es hier um C#.
Und da gibts mit Newtonsoft.JSON ein Library das das komplett übernimmt.

man schmeisst das Json da nur rein und bekommt ein deserialisiertes Objekt zurück mit dem man weiter arbeiten kann.

Und selbst für Delphi gibt es superobject. Verstehe nicht, was man da doch selber parsen möchte.

Madas

p80286 21. Mär 2016 11:51

AW: JSON Parsen
 
Zumindest "Lesen können" ist doch recht hilfreich bei der Fehlersuche.
(Das ist nichts gegen Superobject gesagt!!)

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:15 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz