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

Парсинг вложенных групп в cJSON

Добавлено: 14 Сентябрь 2023, 20:10
harry
Наткнулся на некорректный парсинг при наличии повтояющихся имен полей во вложенных группах

Парсим, например, такой JSON

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

{
			"RecipientReceiptMetadata": {
				"ReceiptStatus": "000",
				"ConfirmationMetadata": {
					"ReceiptStatus": "111",
					"DateTimeTicks": 637852826568038296
				}
			},
			"ConfirmationMetadata": {
				"ReceiptStatus": "222",
				"DateTimeTicks": 637852826113117146
			},
			"AmendmentRequestMetadata": {
				"AmendmentFlags": 3,
				"ReceiptStatus": "333"
			}
}			

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

_DD_ReceiptStatus         Group,Type
ReceiptStatus                      string(40)
                                end

_DD_ConfirmationMetadata        Group(_DD_ReceiptStatus),Type
DateTimeTicks                      string(40)
                                end
_DD_RecipientReceiptMetadata    Group(_DD_ReceiptStatus),Type
ConfirmationMetadata               Group(_DD_ConfirmationMetadata)
                                end

_DD_AmendmentRequestMetadata    Group(_DD_ReceiptStatus),Type
AmendmentFlags                     string(10)
                                end

Document                        Group
RecipientReceiptMetadata           Group(_DD_RecipientReceiptMetadata).
ConfirmationMetadata               Group(_DD_ConfirmationMetadata). 
AmendmentRequestMetadata           Group(_DD_AmendmentRequestMetadata). 
                            end
  Code
  ret# = parser.ToGroup(Document)							
В результате,

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

Document.RecipientReceiptMetadata.ReceiptStatus = '000' !верно
Document.RecipientReceiptMetadata.ConfirmationMetadata.ReceiptStatus = '222' !должно быть '111'
ConfirmationMetadata.ReceiptStatus = '' !должно быть '222'
AmendmentRequestMetadata.ReceiptStatus = '333' !верно
Есть способ решить эту проблему ?

Парсинг вложенных групп в cJSON

Добавлено: 14 Сентябрь 2023, 22:10
Дед Пахом
Не знаю, в одной группе 4 одноимённых поля, трудно определить, к какому полю что из json относится.
**
Переношу тему в форум Библиотеки и шаблоны-cJSON, давайте там новые темы создавать.

Парсинг вложенных групп в cJSON

Добавлено: 15 Сентябрь 2023, 10:31
harry
Видимо, так происходит из-за того , что все элементы группы просматриваются.
В штатном парсере есть код, который в случае не нахождения текущей группы из JSON в структуре группы Clarion , подсчитывает количество элементов в этой группе и пропускает ее. Это решает проблему, но как я понял, этот код создают жуткие тормоза с накопительным эффектом.

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

             !If it is not the name but it is a GROUP then skip all the internal items
             IF ISGROUP(pJSONObject,idx)
                innerGroup &= GETGROUP(pJSONObject, idx,1)
                idx += (SELF.GetGroupNumberOfFields(innerGroup) - 1)
             END

Парсинг вложенных групп в cJSON

Добавлено: 15 Сентябрь 2023, 13:53
Дед Пахом
Я бы предложил такую схему:

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

  jRoot &= jParser.Parse(response)
  IF NOT jRoot &= NULL
    jRoot.ToGroup(MainGroup)
    jRoot.ToGroup('InnerGroup1', InnerGroup1)
    jRoot.ToGroup('InnerGroup2', InnerGroup2)
    
    jRoot.Delete()
  END

Парсинг вложенных групп в cJSON

Добавлено: 16 Сентябрь 2023, 22:08
Дед Пахом
Ну да, вот так работает. Я переименовал имена групп (добавил "Grp" в конец имён), чтобы они НЕ соответствовали именам объектов в json и таким образом не обрабатывались в jRoot.ToGroup(Document).

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

_DD_ReceiptStatus               Group,Type
ReceiptStatus                     string(40)
                                end

_DD_ConfirmationMetadata        Group(_DD_ReceiptStatus),Type
DateTimeTicks                     string(40)
                                end

_DD_RecipientReceiptMetadata    Group(_DD_ReceiptStatus),Type
ConfirmationMetadataGrp           Group(_DD_ConfirmationMetadata)
                                  end
                                END

_DD_AmendmentRequestMetadata    Group(_DD_ReceiptStatus),Type
AmendmentFlags                    string(10)
                                end

Document                        Group
RecipientReceiptMetadataGrp       Group(_DD_RecipientReceiptMetadata).
ConfirmationMetadataGrp           Group(_DD_ConfirmationMetadata).
AmendmentRequestMetadataGrp       Group(_DD_AmendmentRequestMetadata).
ReceiptStatus                     string(40)
                                end

jParser                         cJSONFactory
jRoot                           &cJSON, AUTO
jRecipientReceiptMetadata       &cJSON, AUTO

  CODE
  jRoot &= jParser.Parse(json)
  IF NOT jRoot &= NULL
    !- Читаем корневые данные (вне всех групп)
    jRoot.ToGroup(Document)
    
    !- Читаем группы без вложенных групп
    jRoot.ToGroup('ConfirmationMetadata', Document.ConfirmationMetadataGrp)
    jRoot.ToGroup('AmendmentRequestMetadata', Document.AmendmentRequestMetadataGrp)
    
    !- Читаем группы с вложенными группами
    jRecipientReceiptMetadata &= jRoot.GetObjectItem('RecipientReceiptMetadata')
    IF NOT jRecipientReceiptMetadata &= NULL
      jRecipientReceiptMetadata.ToGroup(Document.RecipientReceiptMetadataGrp)
      jRecipientReceiptMetadata.ToGroup('ConfirmationMetadata', Document.RecipientReceiptMetadataGrp.ConfirmationMetadataGrp)
    END
   
    printd('Document.RecipientReceiptMetadata.ReceiptStatus=%s', Document.RecipientReceiptMetadataGrp.ReceiptStatus)
    printd('Document.RecipientReceiptMetadata.ConfirmationMetadata.ReceiptStatus=%s', Document.RecipientReceiptMetadataGrp.ConfirmationMetadataGrp.ReceiptStatus)
    printd('Document.ConfirmationMetadata.ReceiptStatus=%s', Document.ConfirmationMetadataGrp.ReceiptStatus)
    printd('Document.AmendmentRequestMetadata.ReceiptStatus=%s', Document.AmendmentRequestMetadataGrp.ReceiptStatus)

    jRoot.Delete()
  END