Помогите распарсить JSON ответ VK.api

662 views
Skip to first unread message

Кузьма Корсаков

unread,
Feb 12, 2016, 4:15:08 AM2/12/16
to Golang Russian
Подскажите, пожалуйста, как лучше распарсить JSON


У меня не получается (( как понял, там не совсем правильный JSON, подскажите, что делать?

Daniel Podolsky

unread,
Feb 12, 2016, 4:30:18 AM2/12/16
to gola...@googlegroups.com
с одной стороны - http://json2struct.mervine.net/

с другой - это говноjson, в нем в одном массиве прячутся данные разных
типов, и в go его штатным парсером распотрошить нельзя

так что надо садиться, и писать unmarshalling вручную, или найти умную либу.

я в свое время либу не нашел, но я потратил на это всего полдня. потом
я понял, что у меня есть возможность изменить протокол, и поправил его
в сторону улучшения

возможно, имеет смысл спросить в тематическом слаке про умную либу
> --
> Вы получили это сообщение, поскольку подписаны на группу "Golang Russian".
> Чтобы отменить подписку на эту группу и больше не получать от нее сообщения,
> отправьте письмо на электронный адрес
> golang-ru+...@googlegroups.com.
> Чтобы настроить другие параметры, перейдите по ссылке
> https://groups.google.com/d/optout.

Alex Lurye

unread,
Feb 12, 2016, 4:36:37 AM2/12/16
to gola...@googlegroups.com
encoding/json позволяет написать кастомный Unmarshal только для "кривых" слабо типизированных полей. Надо, чтобы это поле реализовало интерфейс Unmarshaler - типа "если первый символ '[', то разбираем как список, если '{', то как структуру и т.п.) Всё остальное может спокойно разбираться при помощи стандартных средств.

Настройки подписки и доставки писем: https://groups.google.com/d/optout.

Алексей Акулович

unread,
Feb 12, 2016, 4:41:40 AM2/12/16
to Golang Russian
На самом примитивном уровне пока что только так https://play.golang.org/p/xr9vk1KECo 

Daniel Podolsky

unread,
Feb 12, 2016, 4:43:33 AM2/12/16
to gola...@googlegroups.com
> Надо, чтобы это поле реализовало интерфейс Unmarshaler - типа "если первый
> символ '[', то разбираем как список, если '{', то как структуру и т.п.) Всё
> остальное может спокойно разбираться при помощи стандартных средств.

Еще раз - там массив. в котором есть и строки, и указатели на другие
массивы/хеши. Дело даже не в парсере, а в том, что на go такую
структуру предствить адекватно нельзя. Только объявив []interface{}, и
далее делая потом приведение типа вручную/через рефлексию

Alex Lurye

unread,
Feb 12, 2016, 4:50:34 AM2/12/16
to gola...@googlegroups.com
Не, как раз можно по-другому и нужно. Я не знаю VK API, но слышал много жалоб, что иногда полем может быть строка, иногда структура и т.д. Решается примерно так. Например, в поле может прийти или имя человека или список имён людей:

type personList struct {
  names []string
}

func (pl *personList) UnmarshalJSON(data []byte) error {
  switch {
  case len(data) == 0:
    return errors.New("empty JSON chunk")
  case data[0] == '"':
    var name string
    if err := json.Unmarshal(data, &name); err != nil {
      return err
    }
    pl.names = pl.append(names, n)
  case data[0] == '[':
    return json.Unmarshal(data, &pl.names)
  default:
    return errors.New("expected string or list")
  }
}

Т.е вы определяете тип данных так, как это нужно вашему приложению. А декодер кастомизируете, чтобы он говноджейсон раскладывал так, как вам надо.

Daniel Podolsky

unread,
Feb 12, 2016, 5:07:13 AM2/12/16
to gola...@googlegroups.com
> декодер кастомизируете, чтобы он говноджейсон раскладывал так, как вам надо.
без кастомизированного декодера не обойдется по любому.

а дальше или рефлексия/приведение, или структуры данных не
соответствующие структурам в json

Aln Kapa

unread,
Feb 12, 2016, 5:44:39 AM2/12/16
to Golang Russian

Еще интересный вариант показан вот тут http://mattyjwilliams.blogspot.ru/2013/01/using-go-to-unmarshal-json-lists-with.html

SolutionB: Mixed Type struct.

Pasha censored

unread,
Feb 15, 2016, 3:17:57 AM2/15/16
to Golang Russian

Не &version=5.44 , а &v=5.44 и будет тебе норм json
пятница, 12 февраля 2016 г., 12:15:08 UTC+3 пользователь Кузьма Корсаков написал:

Daniel Podolsky

unread,
Feb 16, 2016, 3:42:23 PM2/16/16
to gola...@googlegroups.com
> с другой - это говноjson, в нем в одном массиве прячутся данные разных
> типов, и в go его штатным парсером распотрошить нельзя
Это я, коллеги, вам наврал.

Если штатному парсеру передать interface{} - он спокойно парсит json в
map, со всеми вложенностями.

Извините, я сам не знал :(
Reply all
Reply to author
Forward
0 new messages