Форум программистов, компьютерный форум, киберфорум
Free Pascal
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 07.06.2021
Сообщений: 79
1

Как причесать JSON?

28.07.2021, 11:52. Показов 1565. Ответов 13
Метки нет (Все метки)

Есть JSON, который, к сожалению, после добавления его через TFileStream в файл из проги, выводится как сплошная строка без переносов, где они так необходимы для читаемости. Есть ли какая-то программная функция или механизм, который поможет отформатировать его? Функция .FormatJSON(AsCompressedJSON) не работает
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.07.2021, 11:52
Ответы с готовыми решениями:

Как причесать ревизии в mercurial
Пока учился пользоваться tortoiseHG неправильно работал с ветками. При фиксации изменений...

Как правильно причесать массив?
В элементах массива нужно убрать пробелы и удалить "пустышки". То что я сделал работает почему-то...

Поиск ошибок ну и причесать код
Доброго времени суток Уважаемые форумчане. Нужен взгляд опытных программистов. Задание курсовой:...

Как отправить json post запросом и принят json в ответ?
Вообщем начал постигать новую windows phone... Решил сразу попытаться наладить общение с сервером....

13
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31192 / 20390 / 7940
Регистрация: 22.10.2011
Сообщений: 35,360
Записей в блоге: 6
28.07.2021, 17:43 2
Цитата Сообщение от blackspaceghost Посмотреть сообщение
не работает
Правда?
0
Миниатюры
Как причесать JSON?  
0 / 0 / 0
Регистрация: 07.06.2021
Сообщений: 79
28.07.2021, 17:51  [ТС] 3
volvo, ну что же, я Вас обманывать буду? Возможно косяк в выводе непосредственном, имею ввиду, когда выводится в файл. В файле сплошная строка и баста(
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31192 / 20390 / 7940
Регистрация: 22.10.2011
Сообщений: 35,360
Записей в блоге: 6
28.07.2021, 18:05 4
Ну я же тоже не буду фотошопить вывод, правда? У меня с FormatJSON проблем никогда не было, Всегда он форматирует (да еще и указать можно, как именно форматировать)
0
0 / 0 / 0
Регистрация: 07.06.2021
Сообщений: 79
28.07.2021, 18:30  [ТС] 5
volvo, правда. Остаётся теперь понять, почему у Вас работает, а у меня - нет)
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31192 / 20390 / 7940
Регистрация: 22.10.2011
Сообщений: 35,360
Записей в блоге: 6
28.07.2021, 19:25 6
Не знаю. Влиять может ОС и версия компилятора. Я тестировал под Debian Buster, под Linux Mint 20.1 и под Windows 7. Везде версии компилятора - 3.2.0. Везде прекрасно форматируется.
0
0 / 0 / 0
Регистрация: 07.06.2021
Сообщений: 79
29.07.2021, 09:02  [ТС] 7
Цитата Сообщение от volvo Посмотреть сообщение
Я тестировал под Debian Buster, под Linux Mint 20.1 и под Windows 7.
я тестирую под Ubuntu 20.04.2 LTS, всё так же не фурычит %-(
0
0 / 0 / 0
Регистрация: 07.06.2021
Сообщений: 79
29.07.2021, 09:41  [ТС] 8
volvo, ну вот что я делаю не так? Таким способом тоже выводит сплошную строку. (в if вообще не попадает, почему-то. Вероятно, потому что сам объект сплошной строкой идёт).
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
System.Assign(f, 'd2.json');
        Rewrite(f);
        JSONObject.FormatJSON(AsJSONFormat);
        diff := SizeOfFile - Length(JSONObject.AsJSON);
        for i := 1 to (SizeOfFile-diff) do
          begin
            if JSONObject.AsJSON[i] = #13 then
            begin
               write(f, #13);
               Continue;
            end
            else
              write(f, JSONObject.AsJSON[i]);
          end;
Как причесать JSON?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31192 / 20390 / 7940
Регистрация: 22.10.2011
Сообщений: 35,360
Записей в блоге: 6
29.07.2021, 10:07 9
Можно привести полностью тестовый код (а не его кусок, как сейчас), который не надо будет дописывать, а просто взять, откомпилировать и запустить (вместе с тестовым JSON-ом), чтобы не было потом так, что я допишу и этот код так, что он станет рабочим. Ибо это ни на шаг не приблизит вторую сторону к решению. А вот если будет полный код - сразу станет понятно, работает или нет.

Вот, скажем, мой код полностью:
Кликните здесь для просмотра всего текста
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{$mode objfpc}
uses
  Classes, TypInfo, fpjson, jsonparser;
 
function GetSt(fn : string) : string;
begin
  with TStringList.Create do
  try
    LoadFromFile(fn);
    Result := Text;
  finally
    Free;
  end;
end;
 
const
  fn1 = '/home/volvo/Documents/Programs/test.json';
 
var
  jData : TJSONData;
  L : TStringList;
begin
  L := TStringList.Create;
  try
  
    jData := GetJSON(GetSt(fn1));
    try
      L.Text := jData.FormatJSON;
      writeln(L.Text); // что на консоль
      L.SaveToFile('/home/volvo/Documents/Programs/test_out.json'); // что в файл - выводится отформатированный текст
    finally
      jData.Free;
    end;
    
  finally
    L.Free;
  end;
end.
0
0 / 0 / 0
Регистрация: 07.06.2021
Сообщений: 79
29.07.2021, 11:23  [ТС] 10
Цитата Сообщение от volvo Посмотреть сообщение
Можно привести полностью тестовый код
Можно.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
program Project1;
 
{$mode objfpc}{$H+}
 
uses
 {$IFDEF UNIX}
  cthreads,
     {$ENDIF}
  Classes,
  SysUtils,
  CustApp { you can add units after this },
  crt,
  jsonscanner,
  fpjson,
  jsonparser;
 
 
type
 
  { TMyTimeTest }
 
  TMyTimeTest = class(TCustomApplication)
  private
    fFileData: string;
  protected
    procedure DoRun; override;
  public
    str1, str2, buf: string;
    JSONObject: TJSONObject;
    SizeOfFile: int64;
    constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
    procedure WriteHelp; virtual;
    procedure SetFileData;
    procedure ParseAndSet;
    procedure WriteInFile;
  end;
  { TMyTimeTest }
  procedure TMyTimeTest.SetFileData;
  var
    Strm: TFileStream;
    path: string;
  begin
      if str1 = '' then
        write('Введите путь к искомому JSON: ')
      else
        write('Введите путь ко 2-му JSON: ');
      readln(path);
      try
        try
          Strm := TFileStream.Create(path, fmOpenRead);
          SizeOfFile := Strm.Size;
          SetLength(fFileData, SizeOfFile);
          Strm.Read(fFileData[1], SizeOfFile);
        except
          ShowException(Exception.Create('0'));
          Halt;
 
        end;
      finally
        Strm.Free;
      end;
      if ParamCount = 0 then
        Writeln(ParamStr(0));
 
      if str1 = '' then    //записываем 2 объекта из 2-х файлов соответственно с помощью одной процедуры
        str1 := fFileData
      else if str2 = '' then
        str2 := fFileData;
 
 
 
  end;
 
  procedure TMyTimeTest.ParseAndSet;
  var
    JSONParser1, JSONParser2: TJSONParser;
    JSONObject1, JSONObject2, JNestObject1, JNestObject2:  TJSONObject;
    JSONEnum1, JSONEnum2, JSONNestEnum1, JSONNestEnum2: TBaseJSONEnumerator;
  begin
    JSONParser1 := TJSONParser.Create(str1, DefaultOptions);
    JSONParser2 := TJSONParser.Create(str2, DefaultOptions);
    try
      JSONObject1 := JSONParser1.Parse as TJSONObject;
      JSONObject2 := JSONParser2.Parse as TJSONObject;
      try
        JSONEnum1 := JSONObject1.GetEnumerator;//получаем перечислитель пар
        JSONEnum2 := JSONObject2.GetEnumerator;//получаем перечислитель пар
 
        try
          //проходим по каждой паре в объекте
          while JSONEnum1.MoveNext do
            while JSONEnum2.MoveNext do
              begin
                if JSONEnum1.Current.Value.JSONType = jtObject then //Если тип текущего значения ключа является объектом, тогда
                begin                                               //создаем два новых объекта для двух файлов соответственно, равных значениям объектов-значений ключа
                  JNestObject1 :=  JSONEnum1.Current.Value as TJSONObject;
                  JNestObject2 := JSONObject2.Find(JSONEnum1.Current.Key) as TJSONObject;
                  try
                    JSONNestEnum1 := JNestObject1.GetEnumerator;
                    JSONNestEnum2 := JNestObject2.GetEnumerator;
                    while JSONNestEnum1.MoveNext do
                      while JSONNestEnum2.MoveNext do
                      begin
                        if JSONNestEnum1.Current.Key = JSONNestEnum2.Current.Key then
                        begin
                          if JSONNestEnum1.Current.Value.JSONType = jtString then //если значение является строкой, тогда записываем как строку
                          begin
                            JNestObject2.Strings[JSONNestEnum1.Current.Key] := JSONNestEnum1.Current.Value.AsString; //если ключ первого объекта(JSON файла) соответствует ключу второго объекта(JSON файла),
                            Break;                                                                                   //то перезаписываем ключ второго объекта
                          end
                          else if JSONNestEnum1.Current.Value.JSONType = jtNumber then //если значение является целочисленным, тогда записываем как число
                          begin
                            JNestObject2.Integers[JSONNestEnum1.Current.Key] := JSONNestEnum1.Current.Value.AsInt64;
                            Break;
                          end
                          else if JSONNestEnum1.Current.Value.JSONType = jtBoolean then//если значения является булевым, тогда записываем как булево
                          begin
                            JNestObject2.Booleans[JSONNestEnum1.Current.Key] := JSONNestEnum1.Current.Value.AsBoolean;   //если ключ первого объекта(JSON файла) соответствует ключу второго объекта(JSON файла),
                            Break;
                          end;
                        end;
                        Break;
                      end;
 
                  finally
                     FreeAndNil(JSONNestEnum1);
                     FreeAndNil(JSONNestEnum2);
                  end;
                end
                else if JSONEnum1.Current.key = JSONEnum2.Current.Key then
                begin
                  if JSONEnum1.Current.Value.JSONType = jtString then //если значение является строкой, тогда записываем как строку
                  begin
                    JSONObject2.Strings[JSONEnum1.Current.Key] := JSONEnum1.Current.Value.AsString; //если ключ первого объекта(JSON файла) соответствует ключу второго объекта(JSON файла),
                    Break;                                                                                   //то перезаписываем ключ второго объекта
                  end
                  else if JSONEnum1.Current.Value.JSONType = jtNumber then //если значение является целочисленным, тогда записываем как число
                  begin
                    JSONObject2.Integers[JSONEnum1.Current.Key] := JSONEnum1.Current.Value.AsInt64;
                    Break;
                  end
                  else if JSONEnum1.Current.Value.JSONType = jtBoolean then//если значения является булевым, тогда записываем как булево
                  begin
                    JSONObject2.Booleans[JSONEnum1.Current.Key] := JSONEnum1.Current.Value.AsBoolean; //если ключ первого объекта(JSON файла) соответствует ключу второго объекта(JSON файла),
                    Break;
                  end;
                  Break;
                end;
              Break;
              end;
        finally
           FreeAndNil(JsonEnum1);
           FreeAndNil(JsonEnum2);
 
        end;
      finally
         JSONObject := JSONObject2 as TJSONObject;
         FreeAndNil(JsonObject1);
         //FreeAndNil(JsonObject2);
      end;
 
    finally
      FreeAndNil(JsonParser1);
      FreeAndNil(JsonParser2);
    end;
  end;
 
  procedure TMyTimeTest.WriteInFile;
  var
    Strm: TFileStream;
    diff: int64;
    i,k: integer;
    f: text;
  begin
    try
        Strm := TFileStream.Create('test/d2.json', fmCreate);
        //System.Assign(f, '/media/sf_ResursUSPD/tools/JSON Options Converter/test/uspd2.json');
        //Rewrite(f);
        JSONObject.FormatJSON(AsCompressedJSON);
        diff := SizeOfFile - Length(JSONObject.AsJSON);
        //for i := 1 to (SizeOfFile-diff) do
        //  begin
        //    if JSONObject.AsJSON[i] = #13 then
        //    begin
        //       write(f, #13);
        //       Continue;
        //    end
        //    else
        //    begin
        //      write(f, JSONObject.AsJSON[i]);
        //    end;
        //
    //end;
        //close(f);
 
 
        Strm.Write(JSONObject.AsJSON[1], SizeOfFile-diff); //вычитаем разницу размера файла и размера объекта, чтобы не было NUL в конце файла
    finally
      Strm.Free;
    end;
  end;
 
 
  procedure TMyTimeTest.DoRun;
  var
    ErrorMsg: string;
 
  begin
 
    // quick check parameters
    ErrorMsg := CheckOptions('h', 'help');
    if ErrorMsg <> '' then
    begin
      ShowException(Exception.Create(ErrorMsg));
      Terminate;
      Exit;
    end;
 
    // parse parameters
    if HasOption('h', 'help') then
    begin
      WriteHelp;
      Terminate;
      Exit;
    end;
 
 
    { add your program here }
    Self.SetFileData;
    Self.SetFileData;
    Self.ParseAndSet;
    Self.WriteInFile;
 
 
    Sleep(5000);
 
 
    // stop program loop
    Terminate;
  end;
 
 
 
  constructor TMyTimeTest.Create(TheOwner: TComponent);
  begin
    inherited Create(TheOwner);
    StopOnException := True;
  end;
 
  destructor TMyTimeTest.Destroy;
  begin
    inherited Destroy;
  end;
 
  procedure TMyTimeTest.WriteHelp;
  begin
    { add your help code here }
    writeln('Usage: ', ExeName, ' -h');
  end;
 
var
  Application: TMyTimeTest;
 
begin
  Application := TMyTimeTest.Create(nil);
  Application.Title := 'MyTimeTest';
  Application.Run;
  Application.Free;
end.
Собственно, JSON 1:
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
    "host":{
        "wired": "192.168.1.1",
        "usb_wifi": "192.168.1.2",
        "modem_managed_0": "0.0.0.0"
        },
    "port": {
        "wired": 20002,
        "usb_wifi": 20002,
        "modem_managed_0": 20002
        },
 
    "writedebug": false,
    "writecriticalsection": false,
}
Собственно, JSON 2:
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
    "host":{
        "wired": "0.0.0.0",
        "usb_wifi": "0.0.0.0",
        "modem_managed_0": "0.0.0.0"
        },
    "port": {
        "wired": 20002,
        "usb_wifi": 20002,
        "modem_managed_0": 20002
        },
 
    "writedebug": false,
    "writecriticalsection": false,
    
}
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31192 / 20390 / 7940
Регистрация: 22.10.2011
Сообщений: 35,360
Записей в блоге: 6
29.07.2021, 12:01 11
У меня этот код в принципе не работает:
Код
Exception at 00000000004B577F: EJSONParser:
Error at line 14, Pos 1:Unexpected token (}) encountered.
, ибо json-ы опять битые. А исправлять мне неинтересно. Я же сказал, нужен код, который можно просто взять и запустить. Удачи...
0
0 / 0 / 0
Регистрация: 07.06.2021
Сообщений: 79
29.07.2021, 12:08  [ТС] 12
volvo, извиняюсь, поправил.
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
    "host":{
        "wired": "192.168.1.1",
        "usb_wifi": "192.168.1.2",
        "modem_managed_0": "0.0.0.0"
        },
    "port": {
        "wired": 20002,
        "usb_wifi": 20002,
        "modem_managed_0": 20002
        },
 
    "writedebug": false,
    "writecriticalsection": false
}
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
    "host":{
        "wired": "0.0.0.0",
        "usb_wifi": "0.0.0.0",
        "modem_managed_0": "0.0.0.0"
        },
    "port": {
        "wired": 20002,
        "usb_wifi": 20002,
        "modem_managed_0": 20002
        },
 
    "writedebug": false,
    "writecriticalsection": false
}
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31192 / 20390 / 7940
Регистрация: 22.10.2011
Сообщений: 35,360
Записей в блоге: 6
29.07.2021, 12:14 13
Лучший ответ Сообщение было отмечено blackspaceghost как решение

Решение

Кстати, а что будет, если сделать вот так:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
  procedure TMyTimeTest.WriteInFile;
  var
    L : TStringList;
  begin
    L := TStringList.Create;
    try
        L.Text := Trim(JSONObject.FormatJSON); // (AsCompressedJSON);
        L.SaveToFile('d3.json');
    finally
      L.Free;
    end;
  end;
вместо той процедуры, которая была ранее?

P.S. Чего он так долго работает-то? Мизерные же JSON-ы, Я даже не представляю, что будет, если хотя бы по 20 Kb будет парочка файлов
1
0 / 0 / 0
Регистрация: 07.06.2021
Сообщений: 79
29.07.2021, 13:12  [ТС] 14
Цитата Сообщение от volvo Посмотреть сообщение
Кстати, а что будет, если сделать вот так
огосподибожемой, заработало! Спасибо большое!))
А насчет скорости, так там слип стоит 5-ти секундный, так моментально отрабатывает

Добавлено через 5 минут
Я с самого сначала смотрел на стринглист и что-то он мне не пригляделся... а оно вот как))
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.07.2021, 13:12

Как получить из строки JSON токен используя JSON.NET?
Доброго времени суток, Господа. Поскажите пожалуйста. Я никогда не работал с JSON. Вот тут решил...

Не могу разобраться с тем, как парсить json: response.json as?
не могу разобраться с тем как парсить json response.json as? предполагаю что проблема в том...

JSON Reader. Как прочитать значение переменной в строке JSON
Добрый день! Подскажите пожалуйста как прочитать значение переменной в строке JSON: Есть...

Как распарсить данные из первого json-а и перекинуть их в другой json
Добрый день, столкнулся с такой задачей. Есть вот такой json Необходимо извлечь...

Как правильно прописать коллекцию в JSON конфигурации appsettings.json?
Всем привет. Подскажите, как в appsettings.json правильно прописать список админов? Я здесь...

[JSON.NET] Как десериализовать Json с меняющимеся ключами?
Имеется структура Json ответа вида: { field1: { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.