Personally I'd prefer an option in the writer which allows to filter out empty/null properties when writing. Thereby, one could define an own class like class MyFastWriter : public FastWriter
, override printValue
for handling type objectValue
accordingly and call FastWriter::writeValue
for the rest. Unfortunately, JsonCpp API has defined member function printValue
as private, such that you cannot override it (and not even call it) from a custom derived class.
Hence, I see only three principal ways to achieve what you want: (1) Adapting the json value before writing, (2) defining an own writer class and copying a lot of code from FastWriter
, or (3) change the source code of FastWriter
.
There is already a proper answer for option (1) provided by Jarod42.
Option (2) and (3) share the major drawback that you copy or alter implementation details which might change in future versions of JsonCpp; But still, if one is very aware of the drawbacks coming with altering or copying a library's source code, it might be an option. A situation might be that the json value at hand shall keep empty properties, is very large, and has to be written rather often; then it becomes unhandy to copy the value, altering it just for writing, and writing it then again and again.
I'm for sure not a friend of altering source code; Anyway, see the following adapted version of FastWriter::writeValue
which achieves the output you want:
void FastWriter::writeValue(const Value& value) {
switch (value.type()) {
// cases handling the other value.types remain as is...
...
// case handling objectValue is adapted:
case objectValue: {
Value::Members members(value.getMemberNames());
document_ += '{';
// inserted flag indicating that the first element is to be written:
bool isFirst = true;
for (Value::Members::iterator it = members.begin(); it != members.end();
++it) {
const std::string& name = *it;
// inserted to skip empty/null property values
if(value[name].empty() || value[name].isNull())
continue;
// Replaced: necessary because the first written entry is not necessarily members.begin:
// if (it != members.begin())
// document_ += ',';
if (!isFirst)
document_ += ',';
else
isFirst = false;
// Kept as is...
document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()));
document_ += yamlCompatiblityEnabled_ ? ": " : ":";
writeValue(value[name]);
}
document_ += '}';
} break;
}
}