AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Replace JSON Escape Steuerzeichen

Ein Thema von t2000 · begonnen am 19. Mär 2020 · letzter Beitrag vom 19. Mär 2020
Antwort Antwort
Benutzerbild von t2000
t2000

Registriert seit: 16. Dez 2005
Ort: NRW
232 Beiträge
 
Delphi 12 Athens
 
#1

Replace JSON Escape Steuerzeichen

  Alt 19. Mär 2020, 10:48
Ist das hier die richtige Stelle im Forum?
Soll einfach nur ein Tipp sein.

Ich bekomme über eine REST-Schnittstelle JSON Daten mit Escape-Steuerzeichen. Diese muss ich rausfiltern, bzw. ersetzen.
Da ich nichts gefunden habe, hier meine Routine.

Falls jemand auch sowas sucht

Delphi-Quellcode:
function ReplaceJSONEscape( JSONString: String): String;
// Backslash's ohne richtigen Code bleiben im Text erhalten
var
  p1: Integer;
  l: Integer;
  i: Integer;
  c: Char; // = WideChar
begin
  result := JSONString;
  p1 := pos('\', JSONString);
  l := length(JSONString);
  if (p1 = 0) or (p1 = l) then
    exit;
  c := JSONString[p1+1];
  case c of
    '"' : result := copy( JSONString, 1, p1-1) + '"' + ReplaceJSONEscape( copy( JSONString, p1+2, l-p1-2));
    '\' : result := copy( JSONString, 1, p1-1) + '\' + ReplaceJSONEscape( copy( JSONString, p1+2, l-p1-2));
    '/' : result := copy( JSONString, 1, p1-1) + '/' + ReplaceJSONEscape( copy( JSONString, p1+2, l-p1-2));
    'b' : result := copy( JSONString, 1, p1-1) + #8 + ReplaceJSONEscape( copy( JSONString, p1+2, l-p1-2));
    'f' : result := copy( JSONString, 1, p1-1) + #12 + ReplaceJSONEscape( copy( JSONString, p1+2, l-p1-2));
    'n' : result := copy( JSONString, 1, p1-1) + #10 + ReplaceJSONEscape( copy( JSONString, p1+2, l-p1-2));
    'r' : result := copy( JSONString, 1, p1-1) + #13 + ReplaceJSONEscape( copy( JSONString, p1+2, l-p1-2));
    't' : result := copy( JSONString, 1, p1-1) + #9 + ReplaceJSONEscape( copy( JSONString, p1+2, l-p1-2));
    'u' : begin
            if l < (p1+5) then
              exit;
            i := StrToIntDef('$' + copy( JSONString, p1+2, 4), 0);
            if i = 0 then
              exit;
            result := copy( JSONString, 1, p1-1) + char(i) + ReplaceJSONEscape( copy( JSONString, p1+6, l-p1-6));
          end
    else
      result := copy( JSONString, 1, p1) + ReplaceJSONEscape( copy( JSONString, p1+1, l-p1-1));
  end; // case
end;
Thomas
(Wir suchen eine(n) Entwickler(in) mit Ambitionen später ggf. die Softwarefirma zu leiten)
Aktuell nicht mehr. Aber ab vielleicht 2024/2025 wird das wieder sehr interessant!
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Replace JSON Escape Steuerzeichen

  Alt 19. Mär 2020, 11:04
Alternativ könntest du auch ne JSON Klasse benutzen (System.JSON - TJSONObject etc) die dir das intern alles schon abnimmt und du dir überhaupt keine Gedanke um sowas machen musst.
Sowas ist die halbe Garantie dass irgendwann irgendwas nicht funktioniert.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von t2000
t2000

Registriert seit: 16. Dez 2005
Ort: NRW
232 Beiträge
 
Delphi 12 Athens
 
#3

AW: Replace JSON Escape Steuerzeichen

  Alt 19. Mär 2020, 11:37
Das wollte ich ja, aber unter Delphi habe ich nichts gefunden, was die Steuerzeichen entfernt oder mir daraus ein TJSONObject macht. Wenn es da etwas gibt, dann sag es mir bitte.
Ich nutze intern NUR TJSONObject. Bekomme aber einen String mit Steuerzeichen geliefert.
Thomas
(Wir suchen eine(n) Entwickler(in) mit Ambitionen später ggf. die Softwarefirma zu leiten)
Aktuell nicht mehr. Aber ab vielleicht 2024/2025 wird das wieder sehr interessant!
  Mit Zitat antworten Zitat
Benutzerbild von t2000
t2000

Registriert seit: 16. Dez 2005
Ort: NRW
232 Beiträge
 
Delphi 12 Athens
 
#4

AW: Replace JSON Escape Steuerzeichen

  Alt 19. Mär 2020, 11:57
Vielleicht habe ich aber auch ein Fehler gemacht.

Wenn ich den Umweg über einen String gehe, kann ich mir die eigene Routine sparen.
Das erste Beispiel erzeugt eine Exception, aber das zweite Beispiel funktioniert.
Aber einen direkten weg das Object zu erzeugen habe ich nicht gefunden.

Delphi-Quellcode:
// Übergabe an diese Funktion AParam bzw. LParam : TJSONObject;
var
  FJSONData : TJSONObject;
  FJSONDataString : String;
begin
  // ****** Exception
  FJSONData := LParam.GetValue<TJSONObject>( sngTypeJSONName_Parameter_JSONData); // Das verursacht eine Exception weil ein "-Zeichen mit einem Steuerzeichen versehen ist: Exception bei \"
  // *******

  FJSONDataString := LParam.GetValue<string>( sngTypeJSONName_Parameter_JSONData); // Das funktioniert und die Backslashs sind weg
  //FJSONDataString := ReplaceJSONEscape(FJSONDataString); // Dies ist also nicht notwendig
  FJSONData := TJSONObject.ParseJSONValue( FJSONDataString) as TJSONObject; // und hier erzeuge ich mein TJSONObject
Thomas
(Wir suchen eine(n) Entwickler(in) mit Ambitionen später ggf. die Softwarefirma zu leiten)
Aktuell nicht mehr. Aber ab vielleicht 2024/2025 wird das wieder sehr interessant!
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#5

AW: Replace JSON Escape Steuerzeichen

  Alt 19. Mär 2020, 12:38
Kannst du mal ein Beispiel mit konkreten Daten geben? Insbesondere, wie wird LParam mit was gefüllt und was steht in sngTypeJSONName_Parameter_JSONData?
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von t2000
t2000

Registriert seit: 16. Dez 2005
Ort: NRW
232 Beiträge
 
Delphi 12 Athens
 
#6

AW: Replace JSON Escape Steuerzeichen

  Alt 19. Mär 2020, 17:13
Klar, hier mal ein konkretes Beispiel:

Ich nutze TMS XData Framework für meine REST Kommunikation
Auf Serverseite habe ich folgende REST-Funktion

function TMeineFunc.CheckSvcRunning(const Param: TJSONObject) : TJSONObject; Diese wird aufgerufen und von dort möchte ich als erstes den Parameter überprüfen und in mein eigenes TsngParameter-Object überführen.
Ich rufe also die Create-Routine direkt mit den erhaltenen Daten auf.

Die Daten lauten (Beispiel) STRG-F7 -> AParam.toString ->
'{"Function":"CheckSvcRunning","Version":"10000"," Data":"{\"Services\":[\"75CBA3B2-0970-4278-9170-AEE6920587B1\",\"75CBA3B2-0970-4278-9170-AEE6920587B1\"]}"}'

Die Funktion sollte das gleiche Ergebnis liefern, wenn die gesamten Daten nochmals in {"Param":{...}} gekapselt wären. Daher die ersten Zeilen im Create Constructor

Man sieht, dass das interne Objekt die Backslashes hat. Die direkte Erstellung hat die Exception geliefert. Der Umweg über den String funktioniert aber.

Hier nochmal der ganze Code:

Delphi-Quellcode:
const
  sngType_ExceptionResult = 'Exception';
  sngTypeJSONName_Parameter = 'Param';
  sngTypeJSONName_Parameter_sngFunction = 'Function';
  sngTypeJSONName_Parameter_Version = 'Version';
  sngTypeJSONName_Parameter_JSONData = 'Data';

constructor TsngParameter.Create( const AParam: TJSONObject);
var
  LParam: TJSONObject;
  FJSONDataString: String;
begin
  try
    // Wenn das JSON in einem Parameter-Feld enthalten ist, dann auspacken, falls nicht, direkt zugreifen
    if AParam.GetValue( sngTypeJSONName_Parameter) <> nil then
      LParam := AParam.GetValue<TJSONObject>( sngTypeJSONName_Parameter)
    else
      LParam := AParam;

    FsngFunction := LParam.GetValue<string>( sngTypeJSONName_Parameter_sngFunction);
    FVersion := LParam.GetValue<string>( sngTypeJSONName_Parameter_Version);
    SetVersionCode(FVersion);

    //FJSONData := LParam.GetValue<TJSONObject>( sngTypeJSONName_Parameter_JSONData); Exception bei \"
    FJSONDataString := LParam.GetValue<string>( sngTypeJSONName_Parameter_JSONData);
    //FJSONDataString := ReplaceJSONEscape(FJSONDataString); nicht notwendig
    FJSONData := TJSONObject.ParseJSONValue( FJSONDataString) as TJSONObject;

  except
    on e: Exception do begin
      FsngFunction := sngType_ExceptionResult;
      FVersion := e.Message;
      FJSONData := nil;
    end;
  end;
end;
Thomas
(Wir suchen eine(n) Entwickler(in) mit Ambitionen später ggf. die Softwarefirma zu leiten)
Aktuell nicht mehr. Aber ab vielleicht 2024/2025 wird das wieder sehr interessant!
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#7

AW: Replace JSON Escape Steuerzeichen

  Alt 19. Mär 2020, 17:27
OK, der Wert in "Data" ist in diesem Fall tatsächlich ein String und kein JSON Objekt, sonst würde er nicht in Anführungszeichen stehen. Insofern ist der Umweg über String notwendig.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#8

AW: Replace JSON Escape Steuerzeichen

  Alt 19. Mär 2020, 17:48
Nur bedingt, zumindestens nicht als String, den man komplett manuell beackert.

Ein JSON-Object aus diesem String erstellen und darüber den Wert abzulesen ist schon gut.
Wobei man sich auch überlegen könnte, warum das ein String ist und nicht direkt als Subobject.
Code:
'{"Function":"CheckSvcRunning","Version":"10000","Data":{"Services":["75CBA3B2-0970-4278-9170-AEE6920587B1","75CBA3B2-0970-4278-9170-AEE6920587B1"]}}'
Also ob man den "Makel" hier nicht besser auf Seite des Senders schon beheben könnte.

Zitat:
" Data":
Wollte erst fragen, ob da beim Data wirlich ein Leerzeichen ist, aber das hat's Forum da reingeschmugglt.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von t2000
t2000

Registriert seit: 16. Dez 2005
Ort: NRW
232 Beiträge
 
Delphi 12 Athens
 
#9

AW: Replace JSON Escape Steuerzeichen

  Alt 19. Mär 2020, 18:28
...Also ob man den "Makel" hier nicht besser auf Seite des Senders schon beheben könnte.
Ich sende selber. Ein korrektes TJSONObject. Aber das muss wohl irgendwo im TMS XData so konvertiert werden.
Aber mit der Funktion bin ich auf der sicheren Seite, falls ich den Server für fremde Entwicker freigebe. Und wer weiß, wie andere "Sender" hier Daten verschicken.
Ich bin ja schon froh, das es doch recht einfach alles funktioniert. Und ich kann mit dem RESTED Plugin mit Firefox oder Chrome wirklich sehr gut (mal eben) testen.
Thomas
(Wir suchen eine(n) Entwickler(in) mit Ambitionen später ggf. die Softwarefirma zu leiten)
Aktuell nicht mehr. Aber ab vielleicht 2024/2025 wird das wieder sehr interessant!
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:21 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz