Russian Qt Forum
Март 29, 2024, 01:03 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: JSON для key не зависящих от регистра  (Прочитано 5703 раз)
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[]() - это выход?
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #1 : Апрель 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();
}
 
 
« Последнее редактирование: Апрель 28, 2016, 19:32 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
RustAlex
Гость
« Ответ #2 : Апрель 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();
 
Записан
RustAlex
Гость
« Ответ #3 : Май 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

Где туплю?
Записан
chabapok
Гость
« Ответ #4 : Май 26, 2016, 21:14 »

По сути, предлагается искать нужные ключи последовательным перебором.

Это ж будет ужас по производительности, на сколь-нибудь больших json-ах.

Нормальный способ - подставить парсеру свою container factory, в которой отдавать наследника QJsonObject с перегруженным insert, который делал бы toLowercase.
парсер при создании json-структуры делает не напрямую new QJsonObject, а пользуется фабрикой.

Я не очень в QT, но бегло посмотрев исходники парсера, так и не смог представить, как подобное сделать.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.187 секунд. Запросов: 24.