Qt - JSON с комментариями - PullRequest
       13

Qt - JSON с комментариями

0 голосов
/ 25 августа 2018

Я знаю, что комментирование в стиле C / C ++ (// ..., /* ... */) в JSON недопустимо , но потому что люди с чем-то, называемым sense (не знают, что это есть) намеренно сделанные способы использования недопустимого JSON, например JSON minify или RapidJSON .

Поскольку Qt поставляется с собственными классами JSON Я был (не) удивлен, не обнаружив ничего о комментировании. Так что вопрос ...

Пример входного файла:

test.json:

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

Предоставляет ли Qt какой-либо способ использовать (недопустимый) JSON с комментариями или мне нужно использовать другую библиотеку для этого?

1 Ответ

0 голосов
/ 26 августа 2018

Как я упоминал в комментариях выше, вы можете использовать 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;
}

Конечным результатом является то, что возвращаемое значение вышеуказанной функции является допустимой строкой 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
...