cJSON: Формат полей для вложенных структур

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7322
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

cJSON: Формат полей для вложенных структур

Сообщение Игорь Столяров »

Привет всем !

Подскажите пожалуйста, как можно задать формат экспорта для вложенных структур данных ?
Демонстрационный пример:

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

MyDoc    Group
Content    String('Doc Content')
Review     Group  ! Упрощаем - здесь QUEUE
Content      &String
           end
         end
Params   &cJson
  Code
  MyDoc.Review.Content &= New(String(20))  ! Текст рецензии
  MyDoc.Review.Content  = 'Review Content'

  Params &= json::CreateObject(MyDoc,,'[{{"name":"Review.Content","IsStringRef":true}]')  ! Не работает для Review.Content
  Params &= json::CreateObject(MyDoc,,'[{{"name":"Content","IsStringRef":true}]')  ! Затирает значение MyDoc.Content
В реальных структурах часто повторяются имена полей в разных группах, пока удаётся задавать для них один тип данных ...
Спасибо !
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

Такой код

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

MyDoc                         GROUP
Content                         STRING('Doc Content')
Review                          GROUP
Content                           STRING('Review')
                                END
                              END
jParams                       &cJSON
  Code
  jParams &= json::CreateObject(MyDoc)
  printd(jParams.ToString())
  jParams.Delete()
  
и вывод: {"content":"Doc Content","review":{"content":"Review"}}
С уважением, ДП
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

То есть я не совсем понял вопрос про один тип данных.
С уважением, ДП
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

Понял. Ну тут надо слегка извернуться, внутреннему Content дать уникальное внешнее имя (ReviewContent), а в опциях вернуть оригинальное имя ("JsonName":"content"), тогда работает:

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

MyDoc                         GROUP
Content                         STRING('Doc Content')
Review                          GROUP
Content                           &STRING,NAME('ReviewContent')
                                END
                              END
jParams                       &cJSON
  CODE
  MyDoc.Review.Content &= NEW STRING(20)
  MyDoc.Review.Content = 'Review'
  
  jParams &= json::CreateObject(MyDoc,,'{{"name":"ReviewContent","JsonName":"content","IsStringRef":true}')
  printd(jParams.ToString())
  jParams.Delete()
  DISPOSE(MyDoc.Review.Content)
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7322
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

cJSON: Формат полей для вложенных структур

Сообщение Игорь Столяров »

Дед Пахом писал(а): 17 Ноябрь 2022, 17:09 Ну тут надо слегка извернуться
Спасибо. До такого я сам бы не додумался. Но ! Я сам нашёл "IsStringRef", т.е. не безнадёжен ... ;)
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

Дело слегка упрощается, если сразу объявлять поля с уникальными именами.

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

MyDoc                         GROUP
Content                         STRING('Doc Content')
Review                          GROUP
ReviewContent                     &STRING
                                END
                              END
jParams                       &cJSON
  CODE
  MyDoc.Review.ReviewContent &= NEW STRING(20)
  MyDoc.Review.ReviewContent = 'Review'
  
  jParams &= json::CreateObject(MyDoc,,'{{"name":"ReviewContent","JsonName":"content","IsStringRef":true}')
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7322
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

cJSON: Формат полей для вложенных структур

Сообщение Игорь Столяров »

Спасибо. Да, я уже понял, что кроме имени переменной, внешнего имени в Clarion, теперь есть ещё и JSON имя.
Это сильно упрощает формирование регистрозависимых запросов (например реестры в Сбер СБП).
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7322
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

cJSON: Формат полей для вложенных структур

Сообщение Игорь Столяров »

Ещё раз спасибо за "JsonName" - это многое меняет в качестве кода ... но есть вопрос.
Нет ли возможности групповой установки параметров полей ?

Поясню. Есть большие структуры описания документов, где для каждого вида документа выгружаются
общие поля и какой-то свой набор параметров. Причём поля надо именно исключать, а не паредавать пустые
(особенно указатели на вложенные списки). Т.е. что-то вроде (упрощённый концепт):

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

MyDoc                         GROUP
Name                            STRING(20)
Field01                          Long
Field02                          &Queue
Field02Instance                  Long
...
Field99                          String(36)
                              end
jParams                       &cJSON
  CODE
  jParams &= json::CreateObject(MyDoc,,'{{"name":"_ALL_FIELD_","ignore":true},' & |
                   {{"name":"Name","ignore":False},{{"name":"Field45","ignore":False},{{"name":"Field64","ignore":False}')
  !jParams.ToString() --> Выгрузили 3 поля: Name, Field45, Field64. Красота ведь ?
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

В принципе звёздочка (вместо _ALL_FIELD_) есть: "name" : "*". Но она задумывалась для случаев, когда задаются свойства для всех полей без исключения. Надо бы исправить функцию FindFieldRule, попробуйте такой вариант, если норм, то я обновлю:

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

FindFieldRule                 PROCEDURE(STRING fldName, *TFieldRules rules)
qIndex                          LONG, AUTO
  CODE
  !- search for a rule for fldName
  LOOP qIndex = 1 TO RECORDS(rules)
    GET(rules, qIndex)
    IF LOWER(rules.Name) = LOWER(fldName)
      !- found
      RETURN
    END
  END
  !- no rules found for fldName, search for a generic rule
  LOOP qIndex = 1 TO RECORDS(rules)
    GET(rules, qIndex)
    IF rules.Name = '*'
      !- found
      RETURN
    END
  END
  !- no rules found
  CLEAR(rules)
С уважением, ДП
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

Хотя надо ещё подумать, этот вариант не совсем то.
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7322
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

cJSON: Формат полей для вложенных структур

Сообщение Игорь Столяров »

Всегда готов потестировать !
sm166.gif
sm166.gif (6.69 КБ) 1706 просмотров
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7322
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

cJSON: Формат полей для вложенных структур

Сообщение Игорь Столяров »

Если я правильно понял правила работы правил (не факт), то вопрос решается вот так:

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

FindFieldRule                 PROCEDURE(STRING fldName, *TFieldRules rules)
qIndex                          LONG, AUTO
sIndex                          Long(0)  ! Номер крайнего правила для поля
  CODE
  LOOP qIndex = 1 TO RECORDS(rules)
    GET(rules, qIndex)
    IF LOWER(rules.Name) = LOWER(fldName) OR rules.Name = '*'
      !- found field rules
      sIndex = qIndex !RETURN
    END
  END
  !- not found field rules
  If sIndex = 0 then CLEAR(rules)
  else
     Get(rules,sIndex)
  end
Получилось даже лучше, чем хотел.

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

MyDoc                         GROUP
Name                            STRING(20)
Field01                          Long
Field02                          &Queue
Field02Instance                  Long
...
Field99                          String(36)
                              end
jParams                       &cJSON
  CODE
  jParams &= json::CreateObject(MyDoc,,'{{"name":"*","ignore":true},' & |
                   {{"name":"Name","ignore":False},{{"name":"Field01","IsBool":True},{{"name":"Field02","IsQueue":True}')
  !jParams.ToString() --> Выгрузили 3 поля: Name, Field01, Field02 (массив).
Т.е. наличие для поля ЛЮБОГО индивидального правила, отключает для этого поля ВСЕ предыдущие общие правила.
Проверьте пожалуйста моё кустарное производство. :ty:
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

В Вашем варианте порядок появления правил играет существенную роль. Я на такое не пойду.
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7322
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

cJSON: Формат полей для вложенных структур

Сообщение Игорь Столяров »

Спасибо - понял. Но направление выбрано верное ?
Релиз 2.0: Разделяем правила и применяем общее только если нет индивидуального.

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

FindFieldRule                 PROCEDURE(STRING fldName, *TFieldRules rules)
qIndex                          LONG, AUTO
GeneralRule                     Long(0)
  CODE
  LOOP qIndex = 1 TO RECORDS(rules)
    GET(rules, qIndex)

    If LOWER(rules.Name) = LOWER(fldName)
       RETURN  ! Individual rule for the field
    elsIf rules.Name = '*'
       GeneralRule = qIndex
    end
  END
  
  If GeneralRule > 0 then Get(rules,GeneralRule)  ! General rule for the field
  else
     Clear(rules)  !- not found field rules
  end
Теперь порядок правил не имеет значения, но приоритет у индивидуального:

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

  jParams &= json::CreateObject(MyDoc,,'{{"name":"Name","ignore":False},{{"name":"*","ignore":true},{{"name":"Field02","IsQueue":True}')
  ! Выгружает только поля: Name и Field02 (как массив)
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

Так лучше, но тогда общие правила полностью игнорируются индивидуальными. Пример:
- все поля трактовать как bool
- поле "Expired" переименовать в "IsExpired"

тогда общее правило будет
{"name"="*", "isbool":true}
индивидуальное правило
{"name"="Expired", "jsonname":"IsExpired"}

В Вашем случае isbool не сработает для поля Expired.

Я хочу, чтобы сначала применялись правила для поля, а затем общее правило. То есть если правило
{"name"="Expired", "jsonname":"IsExpired"}
то isbool (true) подтягивается из общего, а если
{"name"="Expired", "jsonname":"IsExpired", "isbool":false}
то применяется явное false.
С уважением, ДП
Закрыто