Personnellement, je préférerais une option dans l'éditeur qui permet de filtrer les propriétés vides/nulles lors de l'écriture. De ce fait, on pourrait définir une propre classe comme class MyFastWriter : public FastWriter
, remplacer printValue
pour gérer le type objectValue
en conséquence et appeler le FastWriter::writeValue
pour le reste. Malheureusement, l'API JsonCpp a défini la fonction membre printValue
comme privée, de sorte que vous ne pouvez pas la remplacer (et même ne pas l'appeler) à partir d'une classe dérivée personnalisée.
Par conséquent, je ne vois que trois façons principales de réaliser ce que vous voulez: (1) Adaptation de la valeur json avant écriture, (2) définition d'une propre classe d'écriture et copie de beaucoup de code de FastWriter
, ou (3) changement le code source de FastWriter
.
Il existe déjà une réponse correcte pour l'option (1) fournie par Jarod42. L'option (2) et (3) partagent l'inconvénient majeur que vous copiez ou modifiez les détails d'implémentation qui pourraient changer dans les futures versions de JsonCpp; Mais encore, si l'on est très conscient des inconvénients liés à la modification ou à la copie du code source d'une bibliothèque, cela peut être une option. Une situation pourrait être que la valeur json en main doit garder des propriétés vides, est très grande et doit être écrite assez souvent; il devient alors difficile de copier la valeur, de la modifier juste pour l'écrire et de l'écrire encore et encore. Je suis à coup sûr pas un ami de la modification du code source; Quoi qu'il en soit, voir la version suivante adaptée de FastWriter::writeValue
qui réalise la sortie que vous voulez:
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