Osobiście wolałbym opcję w programie piszącym, która pozwala odfiltrować puste/puste właściwości podczas pisania. W ten sposób można zdefiniować własną klasę, taką jak class MyFastWriter : public FastWriter
, zastąpić printValue
, aby odpowiednio obsłużyć typ objectValue
i wywołać FastWriter::writeValue
dla reszty. Niestety, JsonCpp API zdefiniował funkcję członka printValue
jako prywatną, tak że nie można jej przesłonić (a nawet wywołać) z niestandardowej klasy pochodnej.
Dlatego widzę tylko trzy główne sposoby osiągnięcia tego, co chcesz: (1) Dostosowanie wartości json przed zapisem, (2) zdefiniowanie własnej klasy pisarzy i skopiowanie dużej ilości kodu z FastWriter
lub (3) zmiana kod źródłowy: FastWriter
.
Istnieje już odpowiednia odpowiedź dla opcji (1) dostarczonej przez Jarod42.
Opcja (2) i (3) mają główną wadę, którą można skopiować lub zmienić szczegóły implementacji, które mogą ulec zmianie w przyszłych wersjach JsonCpp; Ale nadal, jeśli zdajesz sobie sprawę z wad związanych z modyfikacją lub kopiowaniem kodu źródłowego biblioteki, może to być opcja. Może się zdarzyć, że podana wartość json będzie utrzymywać puste właściwości, jest bardzo duża i często musi być zapisywana; wtedy nie jest łatwo skopiować wartość, zmieniając ją tylko po to, by pisać, i następnie ją pisząc.
Jestem na pewno nie przyjacielem zmiany kodu źródłowego; Zresztą, zobacz przystosowany następującą wersję FastWriter::writeValue
która osiąga wyjście chcesz:
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;
}
}
'sed '/: \ W * null \ W *,/d''? – YSC