Страница 1 из 1

cJSON: Проблема парсинга полей с одинаковыми именами

Добавлено: 29 Октябрь 2024, 8:25
Игорь Столяров
Добрый день !

Третий день пытаюсь преодолеть проблему, но всё-таки придётся Вас побеспокоить ... ;)
Я постарался создать минимальный демонстрационный тест, что бы не замылить ошибку:

Код: Выделить всё

TestPublic  Routine

  Data  
G_Info    Group,Type
Flag        Bool
          end
        
G_OnLine  Group,Type
Info        Group(G_Info).  ! ЕСЛИ ЗАКМОМЕНТИРОВАТЬ ВОТ ЭТУ СТРОКУ, тогда qPacket.Info.flag = TRUE и это правильно
          end
          
G_Valid   Group,Type
Online      Group(G_OnLine).
          end          
        
qPacket   Queue(G_Valid)
Info        Group(G_Info).
          end
        
jStr      String('[{{"Info":{{"Flag":true},"Online":{{"Info":{{"Flag":true}}}]')        
Json      cJSONFactory

  Code
  Json.ToQueue(jStr,qPacket,,'[{{"name":"Flag","IsBool":true}]')
  Get(qPacket,1)
  Message(qPacket.Info.flag)  ! = FALSE и это неправильно !!! :(
 !Message(qPacket.Online.Info.flag)  ! = TRUE и это правильно
1. Сначала qPacket.Info.flag = False и это неправильно !

2. Но если убрать из списка qPacket второе поле с именем "Flag" (например закомментировав G_OnLine.Info) -
то всё чудесным образом начинает работать правильно, т.е. qPacket.Info.flag меняет значение на TRUE. :shock:

3. Интересно, что отключить блок с дублирующим именем поля нельзя.
Точнее отключить можно, но проблему это не решает:

Код: Выделить всё

qPacket   Queue
Online      Group
Info          Group   !
Flag            Bool  !
              end     !
            end
Info        Group
Flag          Bool
            end
          end
jStr      String('[{{"Info":{{"Flag":true},"Online":{{"Info":{{"Flag":true}}}]')        
Json      cJSONFactory
  Code          
  ! Не решает проблему :(
  Json.ToQueue(jStr,qPacket,,'[{{"name":"Flag","IsBool":true},{{"name":"Online","ignore":true}]')
  Get(qPacket,1)
  Message(qPacket.Info.flag)  ! = FALSE и это неправильно !!! :(   
Проверьте пожалуйста ! Я уже не знаю, что здесь происходит ... Спасибо !

cJSON: Проблема парсинга полей с одинаковыми именами

Добавлено: 29 Октябрь 2024, 23:31
Дед Пахом
Прогнал через cJSON Mapper, программа выводит

Код: Выделить всё

[2312] [{ 
[2312]   "Info": { 
[2312]    "Flag": true 
[2312]   }, 
[2312]   "Online": { 
[2312]    "Info": { 
[2312]     "Flag": true 
[2312]    } 
[2312]   } 
[2312]  }]

cJSON: Проблема парсинга полей с одинаковыми именами

Добавлено: 30 Октябрь 2024, 5:56
Игорь Столяров
Дед Пахом писал(а): 29 Октябрь 2024, 23:31 Прогнал через cJSON Mapper, программа выводит
Спасибо ! Значит всё ещё хуже, чем я предполагал. :(

OK ! Берём академически правильный код созданный через программу cJSON Mapper,
меняем местами группы Info и Online, и получаем туже самую ошибку.

Т.е. парсинг теперь стал зависим от расположения полей в структуре данных ? :(
Проверьте пожалуйста !

Код: Выделить всё

  Data

sJson                        STRING(''  |
    & '[{{'  |
    & '    "Info":  {{'  |
    & '      "Flag":  true'  |
    & '    },'  |
    & '    "Online":  {{'  |
    & '      "Info":  {{'  |
    & '        "Flag":  true'  |
    & '      }'  |
    & '    }'  |
    & '  }]')

MyArray                      QUEUE
Online                         GROUP
Info                             GROUP
Flag                               BOOL
                                 END
                               END
Info                           GROUP  ! Переместил Info после Online
Flag                             BOOL
                               END                               
                             END

jParser                       cJSONFactory
jRoot                         &cJSON, AUTO
  CODE
  !- JSON -> Clarion
  IF jParser.ToQueue(sJson, MyArray)
    !- Clarion -> JSON
    jRoot &= json::CreateArray(MyArray, TRUE, | 
      '[{"name":"*","IgnoreEmptyObject":true,"IgnoreEmptyArray":true,"EmptyString":"ignore"},' & | 
      '{"name":["Flag"], "IsBool":true},' & | 
      '{"name":["Info","Flag","Online"], "JsonName":"*"}]')
    IF NOT jRoot &= NULL
    
      Get(MyArray,1)
      Message(MyArray.Info.Flag)  ! = False и это ОШИБКА !
    
      !- check result in DebugView
      printd(jRoot.ToString(TRUE))
      jRoot.Delete()
    END
  END
И это ещё не всё ! Теперь смотрим всех. Обратите пожалуйста внимание, что значения просто нет:

Код: Выделить всё

[{
		"online":	{
			"info":	{
				"flag":	1
			}
		}
	}]
а если не менять местами группы (как пример создал cJSON Mapper) - то дейсвительно всё OK:

Код: Выделить всё

[{
		"info":	{
			"flag":	1
		},
		"online":	{
			"info":	{
				"flag":	1
			}
		}
	}]
Вернёмся к исходному вопросу (т.е. к реальной задаче). ;)
Я не могу изменить порядок групп "Online" и "Info" внутри qPacket даже для "временного решения" проблемы.
Внутри qPacket много вложенных групп и если теги внутри объекта не равноправны - то это рушит вообще всю концепцию JSON. :(

Код: Выделить всё

G_Info    Group,Type
Flag        Bool
          end
        
G_OnLine  Group,Type
Info        Group(G_Info).
          end
          
G_Valid   Group,Type
Online      Group(G_OnLine).
          end          
        
qPacket   Queue(G_Valid)
Info        Group(G_Info).
          end
Здесь всё-таки требуется Ваше вмешательсто в данный вопрос. Спасибо ! :)

cJSON: Проблема парсинга полей с одинаковыми именами

Добавлено: 30 Октябрь 2024, 12:21
Дед Пахом
Игорь Столяров писал(а): 30 Октябрь 2024, 5:56 Т.е. парсинг теперь стал зависим от расположения полей в структуре данных ?
Парсинг никакого отношения к структуре данных и полям не имеет. Парсинг это jRoot &= jParser.Parse(json), это разбор строки и получение идентичного строке набора объектов. То, о чём говорите вы, это десериализация - сопоставление (частичное или полное) json с одной стороны и структуры Clarion с другой стороны. ToGroup/ToQueue сопоставляют структуры с учётом жёсткого порядка полей в json. Если нужен произвольный порядок, используйте другие методы.

cJSON: Проблема парсинга полей с одинаковыми именами

Добавлено: 30 Октябрь 2024, 12:27
Игорь Столяров
Дед Пахом писал(а): 30 Октябрь 2024, 12:21 ToGroup/ToQueue сопоставляют структуры с учётом жёсткого порядка полей в json
Так а при чём здесь порядок следования, если поле FLAG находится совсем в другом элементе JSON структуры
(и уровне вложенности структуры данных Clarion) ?!

cJSON: Проблема парсинга полей с одинаковыми именами

Добавлено: 30 Октябрь 2024, 17:30
Дед Пахом
Кажется, начинаю понимать, о чём речь.

cJSON: Проблема парсинга полей с одинаковыми именами

Добавлено: 31 Октябрь 2024, 22:34
Дед Пахом
На FTP версия 1.49.2, дайте знать если косячит, а я пошёл Хэллоуин пьянствовать.

cJSON: Проблема парсинга полей с одинаковыми именами

Добавлено: 01 Ноябрь 2024, 18:03
Игорь Столяров
Информация, если вдруг Вы уже вернулись ... ;)
Спасибо, всё работает штатно, заявленная проблема устранена. :)