Qt - JSON 带注释

Qt - JSON with comments

我知道 C/C++ 风格的注释 (// ..., /* ... */) 在 JSON 中是 invalid but because people with something called sense (don't know what that is) intentionally made ways to use invalid JSON e.g JSON minify or RapidJSON.

因为 Qt 自带 JSON classes 我很(不)惊讶地发现没有评论。所以问题是...

示例输入文件:

test.json:

{
    // This is a comment
    /* This is a another comment */
    "property1": "It's just json",
    "foo": "bar"
}

Qt 是否提供了一些使用(无效)评论的方法 JSON 还是我必须为此使用另一个库?

正如我在上面的评论中提到的,您可以使用 QJSEngine 为您完成大部分繁重的工作。您作为示例提供的字符串本身不会评估为 JSON,但它绝对有效 JavaScript。因此,如果我们可以获得一个 JavaScript 引擎来评估该文本(因此忽略注释),我们可以使用脚本引擎中的内置 JSON 对象来完成将其转换回的所有工作一个字符串。

最简单的做法就是利用 JSEngine 作为您的 JSON 解析器:

QString str = <your json input file that has comments>
QJSValue val = jsengine.evaluate(text);

该表达式的结果是 QJSValue (val) 的实例,它将是完全解析的对象树。您可以使用 QJSValue 上的所有方法来枚举子对象和值。大功告成。

如果您真的想去掉注释以用于不同的 JSON 解析器(包括内置于 Qt 中的解析器),您可以在其上调用 JSON.stringify:

#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;
}

最终结果是上述函数的return值是没有注释的有效JSON字符串。您现在可以将其输入您选择的任何 JSON 解析器。

示例(使用您的示例文件)

 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;

输出:

Result: {"foo":"bar","property1":"It's just json"}

如果您已经是 QML 应用程序,那您就可以开始了。对于控制台或小部件应用程序,您需要引入 QML 库。我将此添加到控制台应用程序的 .pro 文件中:

QT += qml