एसएएस आधार के साथ JSON के चर में यूनिकोड वर्णों के साथ तालिकाओं को पार्स करें



regex parsing (1)

युपीडी
मैन्युअल रूप से json मानचित्र फ़ाइल को संपादित किए बिना मैं समाधान में आया हूं, लेकिन एक regex का उपयोग कर रहा हूं।

libname _all_ clear;
filename _all_ clear;
filename _PDFOUT temp;
filename _GSFNAME temp;
proc datasets lib=work kill memtype=data nolist; quit;
filename jsf '~/sasuser.v94/.json' encoding='utf-8';
data _null_;
  file jsf;
  length js varchar(*);
  retain js;
  input;
  js=unicode(_infile_);
  put js;
  datalines;
{
  "SASJSONExport":"1.0",
  "SASTableData+TEST":[
    {
      "\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f":2,
      "\u0421\u0440\u0435\u0434\u043d\u0435\u0435":4,
      "\u0421\u0442\u0440\u043e\u043a\u0430":"\u0427\u0442\u043e\u002d\u0442\u043e\u0031"
    },
    {
      "\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f":2,
      "\u0421\u0440\u0435\u0434\u043d\u0435\u0435":2,
      "\u0421\u0442\u0440\u043e\u043a\u0430":"\u0427\u0442\u043e\u002d\u0442\u043e\u0032"
    },
    {
      "\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f":1,
      "\u0421\u0440\u0435\u0434\u043d\u0435\u0435":42,
      "\u0421\u0442\u0440\u043e\u043a\u0430":"\u0427\u0442\u043e\u002d\u0442\u043e\u0033"
    }
  ]
}
;
run;
filename jsm '~/sasuser.v94/.json.map' encoding='utf-8';
libname jsd json fileref=jsf map=jsm automap=replace;
libname jsm json fileref=jsm;
data jsmm;
  merge jsm.datasets jsm.datasets_variables;
  by ordinal_DATASETS;
run;
proc sort data=jsmm; by ordinal_root ordinal_DATASETS; run;
data _null_;
  set work.jsmm end=last;
  if _N_=1 then do;
    length s varchar(*) ds varchar(*);
    retain s ds prx;
    s='{"DATASETS":[';
    ds='';
    prx=prxparse('/[^_]/');
  end;
  if ds=dsname then s=s||',';
  else do;
    ds=dsname;
    if _N_^=1 then s=s||']},';
    s=cats(s,'{"DSNAME":"',ds,'","TABLEPATH":"',tablepath,'","VARIABLES":[');
  end;
  s=cats(s,'{"NAME":"',name,'","TYPE":"',type,'","PATH":"',path,'"');
  if prxmatch(prx,name) > length(name) then
    s=cats(s,',"LABEL":"',scan(path,-1,'/'),'"');
  s=s||'}';
  if last then do;
    s=s||']}]}';
    file jsm;
    put s;
  end;
run;
libname jsd json fileref=jsf map=jsm;
proc print data=jsd.SASTableData_TEST label noobs; run;

समाधान का पहला संस्करण
यह त्वरित 'गन्त समाधान' है
सबसे पहले इनपुट डेटा की तैयारी:

libname _all_ clear;
filename _all_ clear;
filename jsf '~/sasuser.v94/.json' encoding='utf-8';
data _null_;
  file jsf;
  length js varchar(*);
  input;
  js=unicode(_infile_);
  put js;
  datalines;
{
  "SASJSONExport":"1.0",
  "SASTableData+TEST": [
    {
      "\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f":2,
      "\u0421\u0440\u0435\u0434\u043d\u0435\u0435":4,
      "\u0421\u0442\u0440\u043e\u043a\u0430":"\u0427\u0442\u043e\u002d\u0442\u043e\u0031"
    },
    {
      "\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f":2,
      "\u0421\u0440\u0435\u0434\u043d\u0435\u0435":2,
      "\u0421\u0442\u0440\u043e\u043a\u0430":"\u0427\u0442\u043e\u002d\u0442\u043e\u0032"
    },
    {
      "\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f":1,
      "\u0421\u0440\u0435\u0434\u043d\u0435\u0435":42,
      "\u0421\u0442\u0440\u043e\u043a\u0430":"\u0427\u0442\u043e\u002d\u0442\u043e\u0033"
    }
  ]
}
;
run;

आउटपुट फ़ाइल। .json :

{
"SASJSONExport":"1.0",
"SASTableData+TEST": [
{
"Переменная":2,
"Среднее":4,
"Строка":"Что-то1"
},
{
"Переменная":2,
"Среднее":2,
"Строка":"Что-то2"
},
{
"Переменная":1,
"Среднее":42,
"Строка":"Что-то3"
}
]
}

फिर json नक्शा फ़ाइल बनाएँ। .json.map :

filename jsmf '~/sasuser.v94/.json.map' encoding='utf-8';
libname jsm json fileref=jsf map=jsmf automap=create;

.json.map सामग्री:

{
  "DATASETS": [
    {
      "DSNAME": "root",
      "TABLEPATH": "/root",
      "VARIABLES": [
        {
          "NAME": "ordinal_root",
          "TYPE": "ORDINAL",
          "PATH": "/root"
        },
        {
          "NAME": "SASJSONExport",
          "TYPE": "CHARACTER",
          "PATH": "/root/SASJSONExport",
          "CURRENT_LENGTH": 3
        }
      ]
    },
    {
      "DSNAME": "SASTableData_TEST",
      "TABLEPATH": "/root/SASTableData+TEST",
      "VARIABLES": [
        {
          "NAME": "ordinal_root",
          "TYPE": "ORDINAL",
          "PATH": "/root"
        },
        {
          "NAME": "ordinal_SASTableData_TEST",
          "TYPE": "ORDINAL",
          "PATH": "/root/SASTableData+TEST"
        },
        {
          "NAME": "____________________",
          "TYPE": "NUMERIC",
          "PATH": "/root/SASTableData+TEST/Переменная"
        },
        {
          "NAME": "______________",
          "TYPE": "NUMERIC",
          "PATH": "/root/SASTableData+TEST/Среднее"
        },
        {
          "NAME": "____________",
          "TYPE": "CHARACTER",
          "PATH": "/root/SASTableData+TEST/Строка",
          "CURRENT_LENGTH": 12
        }
      ]
    }
  ]
}

अनावश्यक डेटासेट का विवरण निकालकर और लेबल जोड़कर, फ़ाइल को थोड़ी-सी बदल दें:

{
  "DATASETS": [
    {
      "DSNAME": "SASTableData_TEST",
      "TABLEPATH": "/root/SASTableData+TEST",
      "VARIABLES": [
        {
          "NAME": "ordinal_root",
          "TYPE": "ORDINAL",
          "PATH": "/root"
        },
        {
          "NAME": "ordinal_SASTableData_TEST",
          "TYPE": "ORDINAL",
          "PATH": "/root/SASTableData+TEST"
        },
        {
          "NAME": "____________________",
          "TYPE": "NUMERIC",
          "PATH": "/root/SASTableData+TEST/Переменная",
          "LABEL": "Переменная"
        },
        {
          "NAME": "______________",
          "TYPE": "NUMERIC",
          "PATH": "/root/SASTableData+TEST/Среднее",
          "LABEL": "Среднее"
        },
        {
          "NAME": "____________",
          "TYPE": "CHARACTER",
          "PATH": "/root/SASTableData+TEST/Строка",
          "LABEL": "Строка",
          "CURRENT_LENGTH": 12
        }
      ]
    }
  ]
}

और फिर प्रयत्न करें:

libname jsd json fileref=jsf map=jsmf;
proc print data=jsd.SASTableData_TEST label noobs; run;

परिणाम:

+--------------+---------------------------+- ----------+---------+-----------+
| ordinal_root | ordinal_SASTableData_TEST | Переменная | Среднее |    Строка |
+--------------+---------------------------+------------+---------+-----------+
|            1 |                         1 |          2 |       4 | Что-то1   |
|            1 |                         2 |          2 |       2 | Что-то2   |
|            1 |                         3 |          1 |      42 | Что-то3   |
+--------------+---------------------------+------------+---------+-----------+

यह सब एसएएस विश्वविद्यालय संस्करण में किया गया था

मैं यूनिक्सोड में वार्स के साथ जेएसओएन को पार्स करने में समस्या का सामना करना पड़ा। इसलिए, मेरे पास अगले JSON (उदाहरण) है:

 {  
   "SASJSONExport":"1.0",
   "SASTableData+TEST":[  
      {  
         "\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f":2,
         "\u0421\u0440\u0435\u0434\u043d\u0435\u0435":4,
         "\u0421\u0442\u0440\u043e\u043a\u0430":"\u0427\u0442\u043e\u002d\u0442\u043e\u0031"
      },
      {  
         "\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f":2,
         "\u0421\u0440\u0435\u0434\u043d\u0435\u0435":2,
         "\u0421\u0442\u0440\u043e\u043a\u0430":"\u0427\u0442\u043e\u002d\u0442\u043e\u0032"
      },
      {  
         "\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f":1,
         "\u0421\u0440\u0435\u0434\u043d\u0435\u0435":42,
         "\u0421\u0442\u0440\u043e\u043a\u0430":"\u0427\u0442\u043e\u002d\u0442\u043e\u0033"
      }
   ]
}

तालिका JSON से पार्स करने के लिए मैं एसएएस इंजन का उपयोग करता हूं:

libname jsonfl JSON fileref=injson ;

कोशिकाओं में कोड उच्च डीकोड वर्ण होता है, लेकिन वार्स का नाम वाल की तरह दिखता है:

+--------------+---------------------------+------------+---------+---------+
| ordinal_root | ordinal_SASTableData_TEST | __________ | _______ | ______  |
+--------------+---------------------------+------------+---------+---------+
|            1 |                         1 |          2 |       4 | Что-то1 |
|            1 |                         2 |          2 |       2 | Что-то2 |
|            1 |                         3 |          1 |      42 | Что-то3 |
+--------------+---------------------------+------------+---------+---------+

शीर्षक को इस तरह दिखना चाहिए:

+--------------+---------------------------+------------+---------+---------+
| ordinal_root | ordinal_SASTableData_TEST | Переменная | Среднее | Строка  |
+--------------+---------------------------+------------+---------+---------+

इसलिए मैंने DIM_N_ वैरिएबल वर्णों को DIM_N_ जैसी नामों के साथ बदलने का फैसला किया है और उसके लिए मुझे सभी स्ट्रिंग मिलनी चाहिए, जो अगले regexp से सहमत हैं: /([\s\w\d\\]+)\"\:/

लेकिन, जेसनसन से स्ट्रिंग प्राप्त करने के लिए मुझे अगले चार '{','}','[',']',',' डेम '{','}','[',']',',' रूप में सेट की आवश्यकता है '{','}','[',']',',' लेकिन अगर वह वर्ण डीएलएम के रूप में सेट करते हैं, तो मैं फिर से जेसन इकट्ठा नहीं करूंगा इसलिए मैंने इसे डीएलएम के रूप में सेट करने के लिए चारों ओर चिपकाने का निर्णय लिया है।

data delim;
    infile injson lrecl=1073741823 nopad;
    file  delim;
    input char1 $char1. @@;
        if char1 in ('{','}','[',']',',') then
            put '7E'x;
        put char1 $CHAR1. @@;
run;

मुझे नोवेलिड जेसन फाइल मिली है:

~
{"SASJSONExport":"1.0"~
,"SASTableData+TEST":~
[  ~
{"\u0056\u0061\u0072":2~
,"\u006d\u0065\u0061\u006e":4~
,"\u004e\u0061\u006d\u0065":"\u0073\u006d\u0074\u0068\u0031"~
}~
,  ~
{"\u0056\u0061\u0072":2~
,"\u006d\u0065\u0061\u006e":2~
,"\u004e\u0061\u006d\u0065":"\u0073\u006d\u0074\u0068\u0032"~
}~
,  ~
{"\u0056\u0061\u0072":1~
,"\u006d\u0065\u0061\u006e":42~
,"\u004e\u0061\u006d\u0065":"\u0073\u006d\u0074\u0068\u0033"~
}  ~
]~
}   

तो अगले चरण के रूप में मैं JSON को पार्स कर रहा हूं और सीमांकक के रूप में उपयोग करता हूं:

data transfer;
length column $2000;
retain r;
    infile delim  delimiter='7E'x nopad;
    input char1 : $4000. @@;
            r = prxparse('/([\s\w\d\\]+)\"\:/');
            pos = prxmatch(r,char1);
            column = prxposn(r,1,char1);
        n= _n_;
run;

यह काम करता है ... लेकिन मुझे लगता है कि ये बहुत बुरा व्यवहार हैं , और यह सीमित है।

UPD1
विकल्प,

options vAlidfmtname=long VALIDMEMNAME=extend VALIDVARNAME=any;

वापसी:

+--------------+---------------------------+----------------------------+---------+--------------+
| ordinal_root | ordinal_SASTableData_TEST |         __________         | _______ |    ______    |
+--------------+---------------------------+----------------------------+---------+--------------+
|            1 |                         1 | авфа2 фвафв = фвыа - тфвыа |       4 | Что-то1 ,,,, |
|            1 |                         2 | авфа2 фвафв = фвыа - тфвыа |       2 | Что-то2      |
|            1 |                         3 | авфа2 фвафв = фвыа - тфвыа |    2017 | Что-то3      |
+--------------+---------------------------+----------------------------+---------+--------------+

तो मेरे सवाल हैं:

  1. क्या मैं infile स्टेटमेंट के बिना पूरी फ़ाइल को डीकोड कर सकता हूं?
  2. क्या मैं infile delimiter उपयोग कर सकता हूं, लेकिन infile delimiter को नष्ट नहीं करने के लिए सेट विकल्प सेट कर सकता हूं?

पर्याप्त आलोचना का स्वागत किया है





sas