Дед Пахом писал(а): 07 Октябрь 2024, 22:14
А давайте вы напишете, чё всё я.
Это батл !

Хотя кого я пытаюсь обмануть, здесь работы на 15 минут даже для меня ...
Предположим, я хочу засабклассить метод ToGroup() что бы он не затирал указатели на вложенные списки.
(*) - Маленькое допущение: что бы не замыливать идею - я не буду копировать сюда код распарса Options.
Код: Выделить всё
ToGroup PROCEDURE(STRING pJson, *GROUP pGrp, BOOL pMatchByFieldNumber = FALSE, <STRING pOptions>) !, BOOL, PROC
BRetVal Bool
Json cJSONFactory
fldRef ANY, AUTO
i LONG, AUTO
qSaveList Queue
Number Long
FldList Any
end
Code
! Сохраняем указатели на вложенные списки в pGrp
LOOP i=1 TO 99999
fldRef &= WHAT(pGrp, i)
IF fldRef &= NULL then Break.
!If fldRule.Instance ! (*) Здесь фильтр по наличию тега "Instance" в Options для поля в pGrp
If InRange(i,2,3)
Clear(qSaveList)
qSaveList.Number = i
qSaveList.FldList = fldRef
Add(qSaveList)
end
end
! Собственно вызываем SELF метод для распарса
BRetVal = Json.ToGroup(pJson, pGrp, pMatchByFieldNumber, pOptions)
! И восстанавливаем указатели на вложенные списки в pGrp
Loop i = Records(qSaveList) to 1 by -1
Get(qSaveList,i)
! Если в pGrp есть поле с номером qSaveList.Number -> восстановить указатель на список
fldRef &= WHAT(pGrp, qSaveList.Number)
If Not fldRef &= NULL then fldRef = qSaveList.FldList.
qSaveList.FldList &= Null ! Очистка ANY поля
Delete(qSaveList)
end
Return BRetVal
И вот теперь да, мы можем без GPF работать с вложенными списками в любезно представленном Вами примере:
Код: Выделить всё
TestPublic Routine
Data
Parser cJSONFactory
!- json string
testString STRING('{{"name": "Carl", "addresses": [{{"city": "Rivercity","street": "Main st","house": 123},{{"city": "Rivertown","street": "Park st","house": 987}], "phones": ["1234567", "7654321"]}')
TypeAddressQ QUEUE,Type
City STRING(20)
Street STRING(20)
House LONG
END
!- address queue
AddressQ QUEUE(TypeAddressQ).
!- phone queue
TypePhonesQ QUEUE,Type
Phone STRING(20)
END
PhonesQ QUEUE(TypePhonesQ).
!- person group
PersonGrp GROUP
Name STRING(20)
Addresses &TypeAddressQ !- reference to AddressQ
Phones &TypePhonesQ !- reference to PhonesQ
END
Addr::Inst LONG, AUTO !- INSTANCE(AddressQ, THREAD())
Phones::Inst LONG, AUTO !- INSTANCE(PhonesQ, THREAD())
qIndex LONG, AUTO
CODE
!- initialize queue references
PersonGrp.Addresses &= AddressQ
PersonGrp.Phones &= PhonesQ
!- read instances of queues in this thread
Addr::Inst = INSTANCE(AddressQ, THREAD())
Phones::Inst = INSTANCE(PhonesQ, THREAD())
!- parse json
If ToGroup(testString, PersonGrp, FALSE, '[{{"name":"Phones", "instance":'& Phones::Inst &'},{{"name":"Addresses", "instance":'& Addr::Inst &'}]')
!- check result
MESSAGE('Name: '& PersonGrp.Name)
! РАБОТАЕМ СО СПИСКАМИ В ГРУППЕ !!!
LOOP qIndex = 1 TO RECORDS(PersonGrp.Addresses)
GET(PersonGrp.Addresses, qIndex)
MESSAGE('Address: '& CLIP(PersonGrp.Addresses.City) &', '& CLIP(PersonGrp.Addresses.Street) &', '& AddressQ.House)
END
LOOP qIndex = 1 TO RECORDS(PersonGrp.Phones)
GET(PersonGrp.Phones, qIndex)
MESSAGE('Phone: '& PersonGrp.Phones.Phone)
END
MESSAGE('Done')
end
Возникунт вопросы или потребуются пояснения - непременно спрашивайте !
