Giter Site home page Giter Site logo

Add ability to serialize just the keys or just the values. This would be very useful when both json and csv are needed. about arduinojson HOT 2 CLOSED

cfeied avatar cfeied commented on May 27, 2024
Add ability to serialize just the keys or just the values. This would be very useful when both json and csv are needed.

from arduinojson.

Comments (2)

cfeied avatar cfeied commented on May 27, 2024

I was able to obtain primitive CSV_Keys and CSV_Values from an ArduinoJson document with the following mods to JsonSerializer.hpp:

I added the following variable to the namespace:

int outFmt = 0;

I then renamed visitObject() to visitObjectForJson() and added branching logic in visitObject as follows:

  size_t visitObject(const CollectionData& object) {
      if (outFmt == 1)
          return visitObjectForCsvKeys(object);
      else if (outFmt == 2)
          return visitObjectForCsvValues(object);
      else
          return visitObjectForJson(object);
  }

  size_t visitObjectForJson(const CollectionData& object) {
      {
          write('{');

          VariantSlot* slot = object.head();

          while (slot != 0) {
              _formatter.writeString(slot->key());
              write(':');
              slot->data()->accept(*this);

              slot = slot->next();
              if (slot == 0)
                  break;

              write(',');
          }

          write('}');

          return bytesWritten();
      }
  }


  size_t visitObjectForCsvKeys(const CollectionData& object) {
      VariantSlot* slot = object.head();
      while (slot != 0) {
          _formatter.writeString(slot->key());

          slot = slot->next();
          if (slot == 0)
              break;

          write(',');
      }
      return bytesWritten();
  }

  size_t visitObjectForCsvValues(const CollectionData& object) {
      VariantSlot* slot = object.head();
      while (slot != 0) {
          slot->data()->accept(*this);

          slot = slot->next();
          if (slot == 0)
              break;

          write(',');
      }
      return bytesWritten();
  }

This seems to do exactly what I wanted (for the kind of data and structures where it could make sense), as shown by the following example:

#include <ArduinoJson.h>
#define OUTPUT_PORT Serial

void setup() {
    OUTPUT_PORT.begin(9600);
  while (!OUTPUT_PORT) continue;

  StaticJsonDocument<200> doc;
  char json[] = "{\"SensorType\":\"GPS\",\"Timestamp\":1351824120,\"Latitude\":48.756080,\"Longitude\":2.302038}";
  DeserializationError error = deserializeJson(doc, json);

  if (error) {
       OUTPUT_PORT.print(F("deserializeJson() failed: "));
       OUTPUT_PORT.println(error.f_str());
       return;
  }

  OUTPUT_PORT.print("\n\n--------------- \nSerializeJson with CSV option \n---------------\n");

  OUTPUT_PORT.print("\n\n-----\nARDUINOJSON_NAMESPACE::outFmt == 0 \nJSON string:\n\n");
  ARDUINOJSON_NAMESPACE::outFmt = 0;
  serializeJson(doc, OUTPUT_PORT);

  OUTPUT_PORT.print("\n\n-----\nARDUINOJSON_NAMESPACE::outFmt == 1 \nCSV header row:\n\n");
  ARDUINOJSON_NAMESPACE::outFmt = 1;
  serializeJson(doc, OUTPUT_PORT);

  OUTPUT_PORT.print("\n\n-----\nARDUINOJSON_NAMESPACE::outFmt == 2 \nCSV data row:\n\n");
  ARDUINOJSON_NAMESPACE::outFmt = 2;
  serializeJson(doc, OUTPUT_PORT);
  OUTPUT_PORT.print("\n\n----------\n\n");

}

void loop() 
{
  // nop
}

Producing the following output:

--------------- 
SerializeJson with CSV option 
---------------


-----
ARDUINOJSON_NAMESPACE::outFmt == 0 
JSON string:

{"SensorType":"GPS","Timestamp":1351824120,"Latitude":48.75608,"Longitude":2.302038}

-----
ARDUINOJSON_NAMESPACE::outFmt == 1 
CSV header row:

"SensorType","Timestamp","Latitude","Longitude"

-----
ARDUINOJSON_NAMESPACE::outFmt == 2 
CSV data row:

"GPS",1351824120,48.75608,2.302038

----------

I'm not submitting a pull request because I know you curate your code very meticulously -- there are better ways to achieve this, obviously, and probably plenty of variant cases to think about. I simply put it out here as food for thought.

Thanks!

Craig

from arduinojson.

bblanchon avatar bblanchon commented on May 27, 2024

Hi Craig,

A function like kv.value.serialize() would make the kv pair iteration much more useful.

This function exists; it's serializeJson().

size_t n = serializeJson(kv.value(), writePtr);

Then, you can use the return value to advance the writing pointer (ensure you don't overflow).

Best regards,
Benoit

from arduinojson.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.