As I alluded to in the comments above, you can use the QJSEngine to do most of the heavy lifting for you. The string you have provided as an example won't evaluate as JSON per se, but it absolutely is valid JavaScript. So if we can get a JavaScript engine to evaluate that text (therefore ignoring the comments), we can use the built-in JSON object in the script engine to do all the work of converting it back to a string.
The simplest thing to do is just to utilize the JSEngine to be your JSON parser:
QString str = <your json input file that has comments>
QJSValue val = jsengine.evaluate(text);
The result of that expression is an instance of QJSValue (val
), which will be the fully parsed object tree. You can use all the methods on QJSValue to enumerate the child objects and values. And you are done.
If you really want to strip the comments off for use with a different JSON parser (including the one built into Qt), you can invoke JSON.stringify on it:
#include <QJSEngine>
#include <QJSValue>
QString stripCommentsOffJSon(const QString& originalText)
{
QJSEngine jsengine;
QString result;
// create an assignment statement so that evaulation works reliably
QString evalExpression = "x=" + originalText + ";";
QJSValue val = jsengine.evaluate(QString(evalExpression));
if (val.isObject() || val.isArray() || val.isNumber() || val.isBool() || val.isNull() || val.isString())
{
QJSValue func = jsengine.evaluate(QString("JSON.stringify"));
QJSValueList funcArgs;
funcArgs.append(val);
QJSValue val2 = func.call(funcArgs);
if (val2.isString())
{
result = val2.toString();
}
}
return result;
}
The end result is that the return value of the above function is a valid JSON string without comments. You can now feed that into any JSON parser of your choice.
Example (using your sample file)
const char* text = "\
{\n\
// This is a comment\n\
/* This is a another comment */\n\
\"property1\": \"It's just json\",\n\
\"foo\": \"bar\"\n\
}";
QString result = stripCommentsOffJSon(QString(text));
std::wcout << L"Result: " << result.toStdWString() << std::endl;
Outputs:
Result: {"foo":"bar","property1":"It's just json"}
If you are already a QML app, you're good to go. For a console or widgets app, you'll need to pull in the QML library. I added this to my .pro file for a console app:
QT += qml