Persönlich würde ich eine Option im Writer bevorzugen, die es ermöglicht, leere/Null-Eigenschaften beim Schreiben herauszufiltern. Dabei könnte man eine eigene Klasse wie class MyFastWriter : public FastWriter
definieren, printValue
für die Behandlung des Typs objectValue
entsprechend überschreiben und FastWriter::writeValue
für den Rest anrufen. Unglücklicherweise hat die JsonCpp-API die Elementfunktion printValue
als privat definiert, sodass Sie sie nicht von einer benutzerdefinierten abgeleiteten Klasse überschreiben (und nicht einmal aufrufen) können.
Daher sehe ich nur drei prinzipielle Möglichkeiten, um zu erreichen, was Sie wollen: (1) Anpassung der Json-Wert vor dem Schreiben, (2) Definieren einer eigenen Writer-Klasse und Kopieren von viel Code von FastWriter
, oder (3) ändern der Quellcode von FastWriter
.
Es gibt bereits eine richtige Antwort für die Option (1) von Jarod42.
Option (2) und (3) teilen den Hauptnachteil, dass Sie Implementierungsdetails kopieren oder ändern, die sich in zukünftigen Versionen von JsonCpp ändern könnten; Aber wenn man sich der Nachteile bewusst ist, die mit dem Ändern oder Kopieren des Quellcodes einer Bibliothek einhergehen, ist dies eine Option. Eine Situation könnte sein, dass der vorliegende json-Wert leere Eigenschaften behält, sehr groß ist und ziemlich oft geschrieben werden muss; dann wird es unhandlich, den Wert zu kopieren, ihn nur zum Schreiben zu ändern und ihn dann immer wieder zu schreiben.
Ich bin sicher kein Freund des Änderns von Quellcode; Wie auch immer, finden Sie in der folgenden angepasste Version von FastWriter::writeValue
, die den Ausgang erreicht Sie wollen:
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