ArduinoJson große json richtig filtern

Hallo zusammen, ich habe eine große Json welche ich auf meinem ESP32 gerne filtern würde. Zum Test wollte ich mir gerne erstmal nur eine Sache ausgeben lassen und es dann nach und nach erweitern, leider klappt das nicht so ganz.

Ich habe mir meinen Filter mit dem Assistant erstellt und dort zeigt er mir in der Vorschau auch die richtige Ausgabe an, ich habe mal einen Demo Sketch erstellt zum selbst prüfen.

Folgende Syntax habe ich im Assistant eingegeben:

{
  "svcResL": [
    {
      "res": {
        "outConL": {
          "0": {
            "secL": {
              "0": {
                "jny": {
                  "dirTxt": true
                }
              }
            }
          }
        }
      }
    }
  ]
}

Aber es kommt folgendes bei raus:
image

test.ino

#include <ArduinoJson.h>

#include "data.h"

// The filter: it contains "true" for each value we want to keep
StaticJsonDocument<200> filter;
StaticJsonDocument<1000> doc;

void setup() {
  Serial.begin(115200);
  filter["svcResL"][0]["res"]["outConL"]["0"]["secL"]["0"]["jny"]["dirTxt"] = true;

  deserializeJson(doc, (const __FlashStringHelper*) sampleJSON, DeserializationOption::Filter(filter));
  serializeJsonPretty(doc, Serial);
}

void loop() {}

data.h im Anhang
data.h (169,7 KB)

1 Like

Ihnen fehlt die Option DeserializationOption::NestingLimit(17), aber ich bin mir nicht sicher, ob das ausreicht. Möglicherweise haben Sie Probleme mit der Speichergröße

Das ist optional und nur eine Schutzmaßnahme. Ändert leider nichts, hatte ich schon probiert.

Ich denke es liegt an einer fehlerhaften Syntax im Filter, ich weiß nur nicht warum der Assistant es richtig anzeigt.

Meinst Du, Deine 169,7 KByte passen in 1000 Byte StaticJsonDocument<1000> doc;?

Gruß Tommy

Ja, weil es doch gefiltert wird, das ist ja die funktion der Libary um mit solchen großen Dateien umzugehen. Der Assistant gibt übrigens sogar noch weniger vor.

PROGMEM tut nichts auf einem ESP32
Der an deserializeJson() übergebene Typ könnte also const char * sein

Ich habe mich zum testen an deinem Code orientiert.

Dies schadet nicht, um das Programm auf ESP32 zu verwenden, aber es tut nichts. Mein Beispiel hat im Vergleich zu Ihrem ein kurzes JSON-Raw-Literal.

Versuchen Sie es mit so etwas und testen Sie, wie tief Sie in den Filter gehen können.

#include <ArduinoJson.h>
#include "data.h"

StaticJsonDocument<144> filter;
DynamicJsonDocument doc(98304);

void setup() {
  Serial.begin(115200);
  Serial.println("--------- READY ---------");

  filter["svcResL"][0]["res"]["outConL"] = true; // ["0"]["secL"]["0"]["jny"]["dirTxt"]

  DeserializationError error = deserializeJson(doc, sampleJSON, sizeof sampleJSON, DeserializationOption::Filter(filter), DeserializationOption::NestingLimit(17));

  if (error) {
    Serial.print("deserializeJson() failed: ");
    Serial.println(error.c_str());
    return;
  } else {
    serializeJsonPretty(doc, Serial);
  }
}

void loop() {}

Ich habe es probiert und es zeigt alles an.

filter["svcResL"][0]["res"]["outConL"]["0"]= true; funktioniert auch

filter["svcResL"][0]["res"]["outConL"]["0"]["secL"] = true; funktionier nicht (null)

filter["svcResL"][0]["res"]["outConL"]["0"]["secL"]["0"] = true; funktionier wieder

filter["svcResL"][0]["res"]["outConL"][0]["secL"][0]["jny"]["dirTxt"] = true; funktioniert auch

Also liegt es aufjedenfall am filter.

Aber wie bekomme ich nun noch andere Werte gefiltert, wie dTimeS und dTimeR?
Ich habe es hiermit versucht, aber das klappt nicht.

filter["svcResL"][0]["res"]["outConL"][0]["secL"][0]["jny"]["dirTxt"] = true;
filter["svcResL"][0]["res"]["outConL"][0]["secL"][0]["jny"]["stopL"][0]["dTimeS"] = true;
filter["svcResL"][0]["res"]["outConL"][0]["secL"][0]["jny"]["stopL"][0]["dTimeR"] = true;

Führt zu:

{
  "svcResL": [
    {
      "res": {
        "outConL": [
          {
            "secL": [
              {
                "jny": {
                  "dirTxt": "Am Stern"
                }
              },
              {
                "jny": {
                  "dirTxt": "Rasenallee"
                }
              }
            ]
          },
          {
            "secL": [
              {
                "jny": {
                  "dirTxt": "Baunatal"
                }
              }
            ]
          },
          {
            "secL": [
              {
                "jny": {
                  "dirTxt": "Kassel Bahnhof Wilhelmshöhe"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Ich frage mich übrigens auch warum er beispielsweise "Rasenallee" anzeigt, das ist doch nicht im [0] sondern im [1].

Ich bin schon fast an der Lösung.

Das müsste fast die richtige Syntax für den Assistant sein, nur das mit dem dTimeS und dTimeR klappt nicht.

{
  "svcResL": [
    {
      "res": {
        "outConL": [
          {
            "secL": [
              {
                "jny": {
                  "dirTxt": true
                },
                "stopL": [
                  {
                    "dTimeS": true
                  }
                ]
              }
            ]
          }
        ]
      }
    }
  ]
}

Setzen Sie einfach more path im Filterobjekt auf true

Kannst du mir ein Beispiel geben?

Ich habe es hiermit versucht:

filter["svcResL"][0]["res"]["outConL"][0]["secL"][0]["jny"]["stopL"][0]["dTimeS"] = true;

Ich bin gerade auf meinem iPhone und es ist schwierig, die richtige Syntax richtig hinzubekommen. Die Verwendung eines JSON-Struktur-Viewers hilft zu sehen, was benötigt wird

Ich habe es gerade mit probiert

#include <ArduinoJson.h>
#include "data.h"

StaticJsonDocument<144> filter;
DynamicJsonDocument doc(120000);

void setup() {
  Serial.begin(115200);
  Serial.println("--------- READY ---------");

  //filter["svcResL"][0]["res"]["outConL"][0]["secL"][0]["jny"]["dirTxt"] = true;
  filter["svcResL"][0]["res"]["outConL"][0] = true; // ["secL"][0]["jny"]["stopL"][0]["dTimeS"]
  //filter["svcResL"][0]["res"]["outConL"][0]["secL"][0]["jny"]["stopL"][0]["dTimeR"] = true;

  DeserializationError error = deserializeJson(doc, sampleJSON, sizeof sampleJSON, DeserializationOption::Filter(filter), DeserializationOption::NestingLimit(17));

  if (error) {
    Serial.print("deserializeJson() failed: ");
    Serial.println(error.c_str());
    return;
  } else {
    serializeJsonPretty(doc, Serial);
  }
}

void loop() {}

So mit filter["svcResL"][0]["res"]["outConL"][0] = true;

und der JSON sieht so aus

➜ Es gibt also ein Problem, weil alle letzten Array-Einträge (0,1,2) ausgewählt wurden und nicht nur der erste Index. Wahrscheinlich liegt ein Tiefenproblem im Filter vor

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.