CftClub.ru
Клуб специалистов ЦФТ-Банк

JSON \ JSON_DOM

 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Справочник PL/PLUS: Функции, примеры, приёмы
Предыдущая тема :: Следующая тема  
Автор Сообщение
De Mian
Профи


Вступление в Клуб: 26.09.2008
СообщениеВс Авг 11, 2019 00:04   JSON \ JSON_DOM Ответить с цитатой
Полезность: Нет оценки
Интересует работа с JSON как с DOM. наподобие XML_DOM.

Знаю, что в своем решении WEBPROXY ЦФТ используют стороннее решение для работы взятое с https://github.com/pljson/pljson.
Может кто-то в своей работе использует это решение или подобные ему и может поделится примером кода по вкладыванию и считыванию в\из JSON структуры наподобие такой : пара простых полей + составная структура, массив скалярных типов, массив составных структур ? пример ниже.

Для чего это нужно: Есть механизм, основанный на сильном использовании макросов execute\process и перегруженных процедур, который по описанию структуры, генерирует процедуры для парсинга и сбора XML. т.е. для работы с XML достаточно описать структуру, в точности повторяющую XML и процедуры работы с XML будут созданы автоматически.
Выглядит это примерно так - описываем структуру, описываем блок чтения полей из XML и блок вкладывания полей в XML. Поля структуры в свою очередь могут быть другими структурами или массивами структур, и для этих структур так же описаны блоки чтения\записи полей. В итоге всё програмирование заключается просто в последовательном описании структур record. т.е. по сути описанный record становится вроде некоторой такой оснастки для взаимодействия со слоем DOM в направление чтения и записи в конкретный формат(пока только XML).

На текущий момент для этих макросов существует 2 рабочих движка трансляции в код pl/sql - Это обычный XML через движек XML_DOM и через движек ЦФТ-ного интегратора (который везде ставит свои кегли BEGIN_). Есть ещё попытка работы трансляции в PL/SQL через XMLTYPE, но там для генерации XML не особо много свободы(особенно в части атрибутов), т.ч. 3-ий движек очень неказистый такой(просто для прикола).

Появилась идея реализовать 4-ый движек - чтобы структура транслировалась в JSON и JSON в структуру. Но поскольку реальных задач с JSON ещё не было, то как-то не нахожу для себя времени изучить хотя бы https://github.com/pljson/pljson. Но по готовому примеру чтения\записи вполне можно разобраться.

Если есть примеры то просьба скинуть. Поделюсь потом тем что получится.


Пример JSON :
Код:

{
    "firstName": "Иван",
    "lastName": "Иванов",
    "address": {
        "streetAddress": "Московское ш., 101, кв.101",
        "city": "Ленинград",
        "postalCode": "101101"
    },
    "phoneNumbers": [
        "812 123-1234",
        "916 123-4567"
    ],
    "test": [
        {
            "one": 1,
            "two": 2
        },
        {
            "one": 11,
            "two": 22
        }
    ]
}


Так мы "програмируем" работу с XML:
Код:

pragma include(::[SOME_TYPE].[GEN_XML_XMLDOM]); -- или pragma include(::[SOME_TYPE].[GEN_XML_XMLCIT]); или pragma include(::[SOME_TYPE].[GEN_XML_XMLTYPE]);

type Status_rec is record(
      ErrorCode NUMBER,
      ErrorString string(2000)
   );
&PARSE_BEGIN('Status');
   &gen_lib.&PARSE_ATTR_DATA('ErrorCode');  -- чтение аттрибута  ErrorCode
   &gen_lib.&PARSE_DATA('ErrorString'); -- чтение тега ErrorString
&MIDDLE_PART('Status');
   &gen_lib.&GEN_ATTR_DATA('ErrorCode'); -- запись аттрибута ErrorCode
   &gen_lib.&GEN_DATA('ErrorString'); -- запись тега ErrorString
&GEN_END('Status');

type
   Client_REC is record(
                        name string,
                        age integer,
                        status Status_rec
   );
   
&PARSE_BEGIN('Client');
   &gen_lib.&PARSE_DATA('name'); -- чтение тега name
   &gen_lib.&PARSE_DATA('age');  -- чтение тега age 
            &PARSE_DATA('status');  -- чтение тега status, и делее по описанию Status_rec чтение атрибута  ErrorCode и тега  ErrorString
&MIDDLE_PART('Client');
   &gen_lib.&GEN_DATA('name');  -- запись тега name
   &gen_lib.&GEN_DATA('age');  -- запись тега age 
         &GEN_DATA('status');  -- запись тега status, и делее по описанию Status_rec чтение атрибута  ErrorCode и тега  ErrorString
&GEN_END('Client');


В итоге макросы транслируются в набор перегруженных процедур, отличающиеся лишь одним параметром P_OBJ - типом обрабатываемой структуры. Эти процедуры соответственно умеют раскладывать XML в описанные структуры и записывать структуру в XML. В итоге всё программирование XML сводится к перечислению набора полей для чтения XML и для записи в XML.
Код:

   type STATUS_REC is record (
      ERRORCODE   number,
      ERRORSTRING   varchar2(2000)
   );
   procedure PARSE_DATA(P_OBJ OUT STATUS_REC,P_CLOB IN OUT NOCOPY clob,....);
   procedure GEN_DATA(P_OBJ IN STATUS_REC,P_CLOB IN OUT NOCOPY clob.....);

   type CLIENT_REC is record (
      NAME   varchar2(128),
      AGE   pls_integer,
      STATUS   STATUS_REC
   );
   procedure PARSE_DATA(P_OBJ OUT CLIENT_REC,P_CLOB_IN IN clob,....);
   procedure GEN_DATA(P_OBJ IN CLIENT_REC,P_CLOB IN OUT NOCOPY clob,.....);

Приведенный пример делает код для работы с XML такой структуры, но вложенность и сложность может быть любая, в том числе и с массивами структур, массивами массивов и т.п. :
Код:
<elm>
   <name>HELLO</name>
   <age>56</age>
   <status ErrorCode="56">
      <ErrorString>ERROR_BLIN</ErrorString>
   </status>
</elm>


Последний раз редактировалось: De Mian (Пн Авг 12, 2019 10:00), всего редактировалось 2 раз(а)
svn
Профи


Вступление в Клуб: 04.02.2008
СообщениеВс Авг 11, 2019 22:59    Ответить с цитатой
Полезность: Нет оценки
В Oralce 12.2 есть встроенная поддержка JSON
De Mian
Профи


Вступление в Клуб: 26.09.2008
СообщениеВс Авг 11, 2019 23:11    Ответить с цитатой
Полезность: Нет оценки
svn пишет:
В Oralce 12.2 есть встроенная поддержка JSON

Arrow Ключевое тут >>Интересует работа с JSON как с DOM.
Встроенная поддержка JSON, как и поддержка XML, работает при заранее известной структуре данных.
в общей задаче, структура не то что не известна, а в принципе не имеет значения. И тут с данными нужно работать только через интерфейсы к объектной модели.
De Mian
Профи


Вступление в Клуб: 26.09.2008
СообщениеСр Авг 21, 2019 18:09    Ответить с цитатой
Полезность: 2
Всё вопрос закрыт. Объекты с GITHUB достаточно простые в использовании. написал на основе них новый движек JSON для автогениратора.
Итого. теперь такой код транслируется
Код:
type rec1_rec is record(
                  int1 integer:=123,
                  str1 string:='HELLO',
                  bool1 boolean:=TRUE,
                  DAT1   DATE:=trunc(SYSdATE)
                  );

&PARSE_BEGIN('rec1','DECLARE_LIST');
   &gen_lib.&PARSE_DATA('int1');
   &gen_lib.&PARSE_DATA('str1');
   &gen_lib.&PARSE_DATA('bool1');                  
   &gen_lib.&PARSE_DATA('dat1','dd/mm/yyyy HH24:MI:SS');
&MIDDLE_PART('rec1','LIST');
   &gen_lib.&GEN_DATA('int1');
   &gen_lib.&GEN_DATA('str1');
   &gen_lib.&GEN_DATA('bool1');
   &gen_lib.&GEN_DATA('dat1','dd/mm/yyyy HH24:MI:SS');
&GEN_END('rec1','LIST');

type rec2_rec is record(
                  int2 integer:=3333,
                  str2 string:='HELLOHELLO',
                  bool2 boolean:=false,
                  DAT2   DATE:=trunc(SYSdATE)+100,
                  rec2      rec1_rec,
                  list2      rec1_list
                  
                  );
                  
&PARSE_BEGIN('rec2','DECLARE_LIST');
   &gen_lib.&PARSE_DATA('int2');
   &gen_lib.&PARSE_DATA('str2');
   &gen_lib.&PARSE_DATA('bool2');                  
   &gen_lib.&PARSE_DATA('dat2','dd/mm/yyyy HH24:MI:SS');
          &PARSE_DATA('rec2');
          &PARSE_DATA('list2','item');        
&MIDDLE_PART('rec2','LIST');
   &gen_lib.&GEN_DATA('int2');
   &gen_lib.&GEN_DATA('str2');
   &gen_lib.&GEN_DATA('bool2');
   &gen_lib.&GEN_DATA('dat2','dd/mm/yyyy HH24:MI:SS');
          &GEN_DATA('rec2');    
          &GEN_DATA('list2','item');        
&GEN_END('rec2','LIST');   


В PL/SQL код для работы(чтение, разбор,создание) примерно с таким JSON.

Код:
{
   "data1": {
      "data2": {
         "int2": 3333,
         "str2": "HELLOHELLO",
         "bool2": false,
         "dat2": "29/11/2019 00:00:00",
         "rec2": {
            "int1": 123,
            "str1": "HELLO",
            "bool1": true,
            "dat1": "21/08/2019 00:00:00"
         },
         "list2": [{
            "item": {
               "int1": 123,
               "str1": "HELLO",
               "bool1": true,
               "dat1": "21/08/2019 00:00:00"
            }
         }, {
            "item": {
               "int1": 123,
               "str1": "HELLO",
               "bool1": true,
               "dat1": "21/08/2019 00:00:00"
            }
         }, {
            "item": {
               "int1": 123,
               "str1": "HELLO",
               "bool1": true,
               "dat1": "21/08/2019 00:00:00"
            }
         }]
      }
   }
}


Уровень вложенности структур, массивов любой.
буду тестить как выдастся время на быстродействие.
De Mian
Профи


Вступление в Клуб: 26.09.2008
СообщениеВт Дек 24, 2019 09:50    Ответить с цитатой
Полезность: 1
De Mian пишет:
Всё вопрос закрыт. Объекты с GITHUB достаточно простые в использовании. написал на основе них новый движек JSON для автогениратора.....

для инфо .....Ещё в 12.2 появилось вот это
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/arpls/json-types.html#GUID-BDE10AAA-445B-47B5-8A39-D86C8EA99283
Достойная копия идей с GITHUB, но намного красивей вложено в объектную модель (JSON_ELEMENT_T Object\JSON_OBJECT_T Object\JSON_ARRAY_T Object)
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Справочник PL/PLUS: Функции, примеры, приёмы Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru