Дешифровка из json


#1

Здравствуйте! Я пишу одну программку, и мне надо из json кода получить данные. `{$reference System.Web.Extensions.dll} uses System.Collections.Generic, System.Web.Script.Serialization;

type Dic = Dictionary<string, object>; ObjArr = array of object;

begin var json := ReadAllText(‘json.txt’); // ну, или получение другим путем… var jss := new JavaScriptSerializer(); var v := ((jss.DeserializeObject(json) as Dic)[‘result’] as ObjArr); foreach var t in v do begin var x := Dic(t); WritelnFormat(‘message= “{0}”’, x[‘message’]) end; end.`

Когда код типа: {"ok":true,"result":[{"update_id":630436984, "message":"Hi"}]}

Всё работает, но у меня json состоит так: {"ok":true,"result":[{"update_id":630436984, "message":{"message_id":3,"from":{"id":8767688743,"is_bot":false,"first_name":"-","last_name":"-","username":"-","language_code":"ru"}}}]}.

Как мне получить например переменную first_name?


#2

Добавьте пожалуйста ``` в код для того чтоб все строчки в 1 не скомкивало. Как то так:

```

begin

end.

```

Превращается в

begin
end.

При чём на строчках с ``` ничего больше не должно быть.


#3
{$reference System.Web.Extensions.dll}
uses System.Collections.Generic, System.Web.Script.Serialization;

type
  Dic = Dictionary<string, object>;
  ObjArr = array of object;

begin
  
  var json := ReadAllText('json.txt'); // ну, или получение другим путем…
  var jss := new JavaScriptSerializer();
  
  var Head := jss.DeserializeObject(json) as Dic;
  var Res := (Head['result'] as ObjArr)[0] as Dic;
  var Message := Res['message'] as Dic;
  var From := Message['from'] as Dic;
  var Last_name := From['last_name'];
  
  writeln(Last_name);
  
end.

Чтоб понимать к какому типу преобразовывать с as - удобно использовать отладку, или какую то особую функцию, которая во всех подробностях выпишет.


#4

Вот к примеру такую функцию:

{$reference System.Web.Extensions.dll}
uses System.Collections.Generic, System.Web.Script.Serialization;

type
  Dic = Dictionary<string, object>;
  ObjArr = array of object;

const
  tab = char(9);

procedure WriteJson(o: object; tabs: integer := 0);
begin
  if o is Dic then begin
    
    var d := o as Dic;
    writeln('Dic : [');
    foreach var kvp: KeyValuePair<string, object> in d do
    begin
      write(tab * (tabs + 1), '"', kvp.Key, '" : ');
      WriteJson(kvp.Value, tabs + 2);
    end;
    writeln(tab * tabs, ']');
    
  end else if o is ObjArr then begin
    
    var a := o as ObjArr;
    writeln('Arr : [');
    for var i := 0 to a.Length - 1 do
    begin
      write(tab * (tabs + 1), i, ' : ');
      WriteJson(a[i], tabs + 2);
    end;
    writeln(tab * tabs, ']');
    
  end else begin
    
    writeln(o.GetType, '(', o, ')');
    
  end;
end;

begin
  
  WriteJson((new JavaScriptSerializer).DeserializeObject(ReadAllText('json.txt')));
  
end.

У меня она выдала:

Dic : [
	"ok" : System.Boolean(True)
	"result" : Arr : [
			0 : Dic : [
					"update_id" : System.Int32(630436984)
					"message" : Dic : [
							"message_id" : System.Int32(3)
							"from" : Dic : [
									"id" : System.Int64(8767688743)
									"is_bot" : System.Boolean(False)
									"first_name" : System.String(-)
									"last_name" : System.String(-)
									"username" : System.String(-)
									"language_code" : System.String(ru)
								]
						]
				]
		]
]

В ноутпеде++ особо удобно, скобочки подсвечивает.


#5

Спасибо! Она прочитала даже больше(То что я скрыл в соображениях безопасности).


#6

Это как, в джейсоне то?)))


#7

У меня проблема похожая, но посложнее. Пытаюсь переписать под Паскаль это: https://github.com/reiinakano/fast-style-transfer-deeplearnjs. Столкнулся с такой проблемой: все данные нейросети хранятся в файлах без опознавательных знаков, судя по всему-массивы, а размеры массивов в каждом файле-в json. Может, кто сможет помочь разобраться?


#8

Ну давайте файлы, показывайте где json часть. Я сам так то с джейсон-данными последний раз работал в майнкрафте (командные блоки). Разобраться чисто посмотрев на этот код - 5 мин.


#9

Кажется нашёл, вы про это? С чем именно проблемы?


#10

Везёт вам!

Json часть Вы уже нашли. В той же папке найдёте несколько десятков файлов без расширений.

Проблема в том, как прочитать массивы из файлов. В json лежат размеры массивов и имена соответствующих файлов.


#11
  1. Копируем код из самого начала этой темы
type
  Dic = Dictionary<string, object>;
  ObjArr = array of object;

и

  var json := ReadAllText('json.txt'); //всё в виде текста
  var jss := new JavaScriptSerializer(); //штука которая сделает из текста объект
  var Head: object := jss.DeserializeObject(json); //получаем объект. И да, можно в 1 строчку всё написать ;)
  1. Всё что вам нужно занать про строение json:
  • Все пробелы, переносы строки и т.п. могут быть смело удалены, они нужны только если этот код должен читать не только компьютер но и человек (собственно зачем и нужен этот формат в первую очередь);
  • В [] находится массив, то есть если в json.txt [false,0] - Head будет array of object с длинной 2, первый элемент это boolean, второй integer;
  • В {} находится обект произвольного типа, у которого несколько полей, каждое поле имеет имя и значение. В .Net его похоже сделали словарём, ну так то это логично. {"bool val":false,"int val":0} будет словарём c ключами bool val и int val (ну и соответствующими значениями);
  • Ну и последнее - простейшие типы данных. true/false - boolean, 0/1/2 - int32, 0.0/0.5/1.0 - System.Decimal, “some text” - string.
  1. Попробуйте ещё поэкспериментировать с процедурой которую я написал, посмотреть что читается во что и что вообще читается. Ещё если нужны подробности - рекомендую википедию и хабр.

#12

Спасибо, а если массив многомерный? Вы ведь видели структуру.


#13

Элементы массива могут быть чем угодно. То есть при

[
  [false,0],
  ["some string"]
]

Head будет типа array of object с длинной 2.

Первый элемент этого массива будет типа array of object c длинной 2 и элементами boolean(false), и integer(0).

Второй элемент массива в Head будет тоже типа array of object, но c длинной 1. Единственный элемент - string('some string')

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


#14

Похоже, Вы неправильно меня поняли. Я имею ввиду чтение массива не из json, а из файлов Variable. Json содержит только размерность.


#15

Это уже ищите или спрашивайте у разработчиков создавших тот репозиторий, в shape я так понимаю хранятся размеры того что внутри, могу только предположить что всё превращено в 1-мерный массив, путём прохождения каждого элемента. К примеру все элементы первой строчки, за ними сразу все элементы второй и т.п. Или наоборот, по столбикам.


#16

Спасибо! Буду разбираться.


#17

А вот как расшифровать массивы из этого (578,6 КБ) файла? Это веса следующей свёрточной нейросети.


#18

))) Гуглим (ну то есть яндексим) “formatter json онлайн”, открывает первую ссылку, вставляем туда весь этот текст, получаем зависание на 10 мин, … Кхм нет, это не было частью плана… Ну ничего, значит ищем форматер-валидар который можно скачать… Ну идею вы поняли)))


#19

А программно это как сделать? Там массивы типа Single. С форматированием-хрен редьки не слаще, всё равно придётся вручную переписывать в код программы, а затем компилировать, запускать для сохранения в файл.


#20

А можете доходчивей объяснить, что там и зачем делать вручную?