Название: JSON для key не зависящих от регистра
Отправлено: RustAlex от Апрель 28, 2016, 14:54
Можно как-то читать JSON по ключам унифицирующим регистр? Может передаваться объект: "id":"1234"
или "ID":1234
написал метод: C++ (Qt) QString updater::getJsonUpperStr(const QJsonObject &obj, const QString &key) const { if(obj.contains(key)) { if( obj[key].isString() ) return obj[key].toString(); else if( obj[key].isDouble()) return QString::number(obj[key].toInt()); } else { if( obj[key.toUpper()].isString() ) return obj[key.toUpper()].toString(); else if( obj[key.toUpper()].isDouble()) return QString::number(obj[key.toUpper()].toInt()); } }
Но выпадают случаи "Id":... и "iD":... Нет ли готового "велосипеда"? Переопределять operator==() для QJsonObject вроде тоже как не вариант, он же будет работать не для ключей, а для значений... так ведь? Переопределять operator[]() - это выход?
Название: Re: JSON для key не зависящих от регистра
Отправлено: m_ax от Апрель 28, 2016, 19:23
Есть же итераторы и алгоритмы: C++ (Qt) QString updater::getJsonUpperStr(const QJsonObject &obj, const QString &key) const { auto it = std::find_if(obj.begin(), obj.end(), [&](const QJsonValueRef & elem) { return QString::compare(key, elem.key, Qt::CaseInsensitive) == 0; } ); if (it != obj.end()) { return cast_to<QString>(*it); } return QString(); }
или так: C++ (Qt) QString updater::getJsonUpperStr(const QJsonObject &obj, const QString &key) const { for (const auto & elem : obj) { if (QString::compare(key, elem.key, Qt::CaseInsensitive) == 0) return cast_to<QString>(elem.value()); } return QString(); }
Название: Re: JSON для key не зависящих от регистра
Отправлено: RustAlex от Апрель 29, 2016, 14:27
Спасибо. Напрямую предложенный вариант не взлетел... Вот такой вариант заработал: C++ (Qt) QString updater::getJsonUpperStr(const QJsonObject &obj, const QString &key) const { for (const auto & elem : obj.keys()) { if (key.compare( elem, Qt::CaseInsensitive) == 0) if(obj[elem].isString()) return obj[elem].toString(); else return QString::number(obj[elem].toInt()); } return QString();
Название: Re: JSON для key не зависящих от регистра
Отправлено: RustAlex от Май 04, 2016, 13:37
Ожидал сразу же услышать критику, ведь C++ (Qt) return obj[elem].toString();
По сути повторяет проход по JSON объекту. Не понимаю почему не работает вариант: C++ (Qt) foreach (const auto & elem, obj) { if (key.compare( elem.key(), Qt::CaseInsensitive) == 0) if(elem.value().isString()) return elem.value().toString(); else return QString::number(elem.value().toInt()); }
Этот код, на мой взгляд, должен быть эквивалентен: C++ (Qt) foreach (const QJsonObject::iterator & elem, obj) { if (key.compare( elem.key(), Qt::CaseInsensitive) == 0) if(elem.value().isString()) return elem.value().toString(); else return QString::number(elem.value().toInt()); }
но это не так: C++ (Qt) updater.cpp:1586: error: no viable conversion from 'QJsonValue' to 'const QJsonObject::iterator' foreach (const QJsonObject::iterator & elem, obj) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
хотя мне кажется что elem.value() как раз и должен вернуть QJsonValue Где туплю?
Название: Re: JSON для key не зависящих от регистра
Отправлено: chabapok от Май 26, 2016, 21:14
По сути, предлагается искать нужные ключи последовательным перебором.
Это ж будет ужас по производительности, на сколь-нибудь больших json-ах.
Нормальный способ - подставить парсеру свою container factory, в которой отдавать наследника QJsonObject с перегруженным insert, который делал бы toLowercase. парсер при создании json-структуры делает не напрямую new QJsonObject, а пользуется фабрикой.
Я не очень в QT, но бегло посмотрев исходники парсера, так и не смог представить, как подобное сделать.
|