JSON UDF - beim erweitern eines JSON werden Escapezeichen geschrieben

  • Ich spreche eine API an, die API gibt mir Text im JSON Format zurück:

    JSON
    {"ref":"https://blabla","hash":"3882db"}

    Ich nehme das und hänge davon mehrere aneinander. Das sieht dann am Ende so aus:

    JSON
     [{"ref":"https://blabla","hash":"3882db"},{"ref":"https://blabla","hash":"3882db"},{"ref":"https://blabla","hash":"3882db"}]

    Dann mach ich

    AutoIt
    $sString = '[{"ref":"https://blabla","hash":"3882db"},{"ref":"https://blabla","hash":"3882db"},{"ref":"https://blabla","hash":"3882db"}]'
    _JSON_addChangeDelete($oJSON_Ad, "images", $sString)
    $oJSON_Ad = _JSON_Generate($oJSON_Ad)
    ; Write $oJSON_Ad to file ...

    und das klappt auch. Nur in der Datei ist auf einmal der Text mit Escape-Zeichen

    JSON
    {\"ref\":\"https://blabla\",\"hash\":\"3882db\"}

    und das darf natürlich nicht :D

    Danke für Hinweise/Hilfe im Voraus.
    VG Yaerox

    Grüße Yaerox

    Grüne Hölle

    Einmal editiert, zuletzt von SOLVE-SMART (9. Oktober 2025 um 23:27)

  • Ich hab jetzt folgendes Versucht:

    Das scheint zu klappen. Ich habe in dem JSON File jetzt nun ein unnötiges "" aber ich mach mal weiter und schau mal ob das wohl ein Problem wird.

    Grüße Yaerox

    Grüne Hölle

    Einmal editiert, zuletzt von SOLVE-SMART (9. Oktober 2025 um 23:27)

  • Hier fehlt ein bisschen was in deinem größeren Codebeispiel.
    Du hast erst einen JSON-String in der Variable $sString definiert.
    Danach machst du ein _JSON_addChangeDelete() auf die Datenstruktur $oJSON_Ad - keine Ahnung wo die auf einmal herkommt.

    Was ist das für eine Datenstruktur? Wo kommt die her?
    Egal - wir gehen mal davon aus, dass das eine gültige Datenstruktur ist und diese offensichtlich eine Map ist, welche den Key "images" besitzt oder diesen erhalten soll.

    Das Problem bei dir ist, dass du der Map $oJSON_Ad gar keine Datenstruktur hinzufügst sondern einfach nur den JSON-String. Es ist kein Array mit 3 Maps als Elementen - nein es ist einfach nur eine Zeichenkette.
    Und da diese Zeichenkette Zeichen enthält die in JSON eine Bedeutung haben müssen diese natürlich escaped werden.

    Kurz: Du musst aus dem JSON-String erstmal eine AutoIt-Datenstruktur machen - also ein _JSON_Parse. Sonst fügst du einfach nur einen langweiligen String hinzu und keine dadurch beschriebene Datenstruktur.

    Mal als Code zum besseren Verständnis:


    Mal zum Grundverständnis der UDF:
    JSON ist einfach nur ein Format, welches verschachtelte Datenstrukturen in Textform abbildet.
    Ich kann z.B. in Python Dictionaries, Arrays, Strings, Zahlen etc. in irgendeiner verschachtelten Form in einer Variablen gespeichert haben und überführe dies in einen JSON-String.
    In irgendeiner anderen Programmiersprache schnappe ich mir dann den String und bilde diese Datenstruktur anhand des JSON-Strings dort nach.
    JSON ist also nur ein Textformat, welches die Datenstrukturen in Textform gießt zum einfachen Austausch - nicht mehr und nicht weniger.

    Das heißt im Grunde in der ganzen Prozessierung taucht JSON in dem ganzen Prozess nur zweimal auf: Einmal um einen externen _JSON-String in eine AutoIt-Datenstruktur zu überführen: Das macht _JSON_Parse() und einmal am Ende wenn man aus der AutoIt-Struktur einen _JSON_String erzeugen möchte der diese Struktur wiedergibt: Das macht _JSON_Generate() bzw. _JSON_GenerateCompact().

    Alles dazwischen ist im Grunde völlig unabhängig von JSON. Es sind reine AutoIt-Datenstrukturen und müssen auch so behandelt werden.
    Also Maps, Arrays, Strings, Zahlen usw. und üblicherweise auch ineinander verschachtelt.
    Da der Umgang mit derart verschachtelten Daten in AutoIt nicht immer ganz trivial ist, gibt es in der UDF Hilsfunktionen um mit diesen verschachtelten Daten besser zu arbeiten: _JSON_Get() und _JSON_addChangeDelete(). Die haben eigentlich gar nichts mit JSON zu tun sondern nur mit verschachtelten reinen AutoIt-Datenstrukturen. Aber da sie im Kontext von JSON sehr oft notwendig sind tragen sie dies mit im Namen.

    Also kurz: Wenn du einen JSON-String bekommst - egal wann, egal woher - das erste was du machst ist diesen mit _JSON_Parse() in eine AutoIT-Datenstruktur zu überführen.
    Alles was du dann mit den Daten machst ist rein auf Ebene von AutoIt und unabhängig von JSON.
    Je nachdem ob es sinnvoll ist kannst du hierbei die Funktionen _JSON_Get() und _JSON_addChangeDelete() zu Hilfe nehmen aber mit JSON hat das in dieser Phase nichts zu tun.
    Erst wenn du wieder einen JSON-String sehen willst (z.B. beim Ausgeben in eine Datei) dann überführst du die AutoIt-Datenstruktur in einen JSON-String per _JSON_Generate() bzw. _JSON_GenerateCompact().

  • Danke dir AspirinJunkie , wie immer hervorragend erklärt 👌 .

    Hier mal ein anderer Ansatz, im Falle du kannst/möchtest direkt mit der API response arbeiten.
    Vielleicht trifft mein skizziertes Beispiel gar nicht zu, doch evtl. hilft es im Verständnis mit dem Umgang mit JSON (strings).

    Mal angenommen du holst dir per cURL (oder anderen Client) dein JSON string (response) von irgendeiner Webseite.
    Dann könntest du mit jq (jq.exe) deine Zielstruktur direkt erstellen ohne viel machen zu müssen.
    curl -sSL 'https://your-target-website.com/api/get' | jq.exe '{images: .}'

    Ergebnis

    Oder anders, damit es anschaulicher wird: Du hast deinen JSON string in Datei before.json (dies ist der Ersatz für dein cURL Aufruf) [...]
    [{"ref":"https://blabla","hash":"3882db"},{"ref":"https://blabla","hash":"3882db"},{"ref":"https://blabla","hash":"3882db"}]

    [...] nun kannst du, vorausgesetzt du nutzt unter Windows bash oder einen anderen Linux like Terminal (#werbung-für-vscode),
    per cat und jq das gleiche Ergebnis erreichen, in Datei after.json.
    cat before.json | jq '{images: .}' > after.json

    • cat before.json ==> anzeigen des Dateiinhaltes
    • | ==> pipe das Ergebnis der Datei in das nächste Tool/Programm, also jq
    • jq <command> ==> erzeugt deine Zielstruktur
    • > after.json ==> leitet das Ergebnis in die Datei after.json um

    💡 Ich weiß, viele Voraussetzungen und externe Tools, anstatt direkt mit der JSON.au3 und AutoIt zu arbeiten. Doch je nachdem in welchem Kontext du arbeitest oder mit jemanden arbeitest (Team etc.), ist AutoIt wahrscheinlich weniger im Einsatz als jq.

    ⚠️ Ich gebe auch hier nochmal den Hinweis, auch wenn ich weiß das AspirinJunkie meinen Beitrag hier richtig einordnen wird und kein JSON.au3 bashing wahrnimmt 😅 😙 :
    Wenn ich rein in AutoIt unterwegs bin und mit JSON arbeite, dann ist seine UDF aus meiner Sicht die richtige Wahl, unter den vielen JSON UDFs. Sobald ich mit anderen Sprachen, Frameworks etc. arbeite, sind deren JSON Serializer oder eben jq als Alternative, die bessere Wahl - da mehr geläufig. Dies deckt sich im wesentlichen auch mit dem was er bereits angesprochen hat, JSON einlesen, verarbeiten in der Sprache oder Tool der Wahl und JSON weiter verarbeiten oder ausgeben.

    Einen angenehmen Abend euch noch.

    Viele Grüße
    Sven

  • Zunächst sorry, dass ich so spät antworte. Ware bis grad eben das ganze Wochenende unterwegs.

    Ich habe versucht das Problem so knapp wie möglich zu beschreiben weil ich nicht komplett ausholen wollte. Das war vielleicht etwas zu knapp.

    Was ist das für eine Datenstruktur? Wo kommt die her?

    Ich mache ein curl an die gleiche API aber einen anderen Controller. Der gibt ebenfalls JSON zurück. Den Output schreibe ich in eine Datei. Die Datei lese ich ein, mache ein _JSON_Parse und anschließend hole ich mir aus diesem JSON ein Teilstück mit Local $oJSON_Ad = _JSON_Get($oJSON_mobile, "ads.["& $i & "]").

    Du musst aus dem JSON-String erstmal eine AutoIt-Datenstruktur machen

    Mein Ansatz in meiner Antwort mit $MAP scheint bislang zu funktionieren.


    Background: Ich schreibe aktuell paar kleine "Programme" die mit der API von mobile.de arbeiten. Die nutzen dort eigentlich für alles JSON. Du wilst eine Anzeige erstellen, du schickst denen einen JSON. Du willst Informationen auslesen, du kriegst einen JSON. Ich lade mir quasi alle Anzeigen die ich online habe herunter (das ist ein großer JSON den ich da kriege) und möchte diese dann neu hochladen. Auf der Webseite kann man Anzeigen duplizieren, alt löschen und die neue dann "Freischalten". Das geht so nicht via API. Daher erst alle Anzeigen holen, dann muss ich den JSON bearbeiten, da dort die Bilder verlinkt sind. Anschließend lade ich die Bilder neu hoch, wo ich eben diese kurzen JSONs zurück kriege und muss diesen Bilder teil überschreiben (oder löschen und neu hinzufügen). Anschließend kann ich dann neue Anzeigen erstellen mit dem JSON den ich quasi überarbeitet habe.

    Mit fehlt jetzt nur noch der eltzte Baustein, da bin ich grad dann, der erste Teil scheint wie gesagt nun zu klappen.

    PS: Ich weiß nicht mehr wie man inline Code Markup macht, daher Fett schrift oben.

    Grüße

    Grüße Yaerox

    Grüne Hölle

  • Ich hab's nicht ganz herausgelesen: Ist dein Problem gelöst oder ist noch eine Frage offen geblieben?


    Ich mache ein curl an die gleiche API aber einen anderen Controller. Der gibt ebenfalls JSON zurück. Den Output schreibe ich in eine Datei. Die Datei lese ich ein, mache ein

    Der Umweg über Dateien klingt etwas unnötig. Man kann die Ausgabe von curl auch direkt mit AutoIt weiterverarbeiten (mit StdOutRead).

    Und anstatt curl sollte in den allermeisten Fällen auch ein InetRead() reichen.

  • Mein Problem ist mit meiner ersten eigenen Antwort erledigt.

    Der Umweg über Dateien klingt etwas unnötig. Man kann die Ausgabe von curl auch direkt mit AutoIt weiterverarbeiten (mit StdOutRead).

    Und anstatt curl sollte in den allermeisten Fällen auch ein InetRead() reichen.

    Ja ich glaube ich brauche das nicht zwingend. Ich bin grad in Entwicklung, ich werde da noch einiges Optimieren bevor ich das im Echtbetrieb nutze :D Aktuell schreibe ich oft die JSONs in Dateien damit ich nochmal die Inhalte alle gegenprüfen kann :D

    Grüße Yaerox

    Grüne Hölle