BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
sarahzhou
Quartz | Level 8

I have a SAS code: 

%let input_string =%nrbquote([{"OrderID": "A0000123", "OrderDate": "4/30/2010"},{"OrderID": "A0000124", "OrderDate": ""}]);

data json_text;
json_text="&input_String.";
run;

data Parse_JSON (drop=json_text drop=regex01 drop=regex02 drop=regex03 drop=regex04);
set WORK.json_text;
	retain 
		regex01
		regex02
		regex03
		regex04
;
  	if _N_ = 1 then do; 
		regex01=prxparse("/(.+?)OrderID(.+?)OrderDate/"); 
		regex02=prxparse("/(.+?)OrderDate(.+?)\}/"); 
	    regex03=prxparse("/(.+?)OrderID(.+?)OrderDate/"); 
		regex04=prxparse("/(.+?)OrderDate(.+?)\}/"); 
	end;

	if prxmatch(regex01, json_text) then do;
		OrderID1=strip(tranwrd(tranwrd(tranwrd(upcase(prxposn(regex01, 2, json_text)),":",""),",",""),'"',""));
    end;
	if prxmatch(regex02, json_text) then do;
		OrderDate1=input(strip(tranwrd(tranwrd(tranwrd(upcase(prxposn(regex02, 2, json_text)),":",""),",",""),'"',"")),YYMMDD10.);
    end;

    if prxmatch(regex03, json_text) then do;
		OrderID2=strip(tranwrd(tranwrd(tranwrd(upcase(prxposn(regex03, 2, json_text)),":",""),",",""),'"',""));
    end;
	if prxmatch(regex04, json_text) then do;
		OrderDate2=input(strip(tranwrd(tranwrd(tranwrd(upcase(prxposn(regex04, 2, json_text)),":",""),",",""),'"',"")),YYMMDD10.);
    end;
run;

I want to get the output JSON table as

OrderID1OrderDate1OrderID1OrderDate1
A00001234/30/2010A0000124 

 

However, when I run it, I get

OrderID1OrderDate1OrderID1OrderDate1
A0000123 A0000123 

 

How can I fix my code. Kindly help.

Many many thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
ChrisHemedinger
Community Manager

When working with JSON as input, always think of the JSON libname engine first...before resorting to DATA step parsing.

 

filename j temp;

data _null_;
file j;
put '[{"OrderID": "A0000123", "OrderDate": "4/30/2010"},{"OrderID": "A0000124", "OrderDate": ""}]';
run;

libname data json fileref=j;

data output;
 set data.root;
run;

proc print data=output;
run;

 

Learn from the Experts! Check out the huge catalog of free sessions in the Ask the Expert webinar series.

View solution in original post

13 REPLIES 13
ChrisHemedinger
Community Manager

When working with JSON as input, always think of the JSON libname engine first...before resorting to DATA step parsing.

 

filename j temp;

data _null_;
file j;
put '[{"OrderID": "A0000123", "OrderDate": "4/30/2010"},{"OrderID": "A0000124", "OrderDate": ""}]';
run;

libname data json fileref=j;

data output;
 set data.root;
run;

proc print data=output;
run;

 

Learn from the Experts! Check out the huge catalog of free sessions in the Ask the Expert webinar series.
sarahzhou
Quartz | Level 8

Hi, how do I drop root column?

ChrisHemedinger
Community Manager

The ordinal keys are added to help you join multiple tables coming from a single JSON source. 

 

If it's just the one simple table and you don't need them, drop them like so:

 

data output;
 set data.root (drop=ordinal:);
run;
Learn from the Experts! Check out the huge catalog of free sessions in the Ask the Expert webinar series.
sarahzhou
Quartz | Level 8
Thank you!
sarahzhou
Quartz | Level 8

Hi Chris,

When I added a macro "input_string" to control the input strings, the below script run with errors

filename j temp;

%let input_string =%nrbquote({"OrderID1": "A0000123", "OrderDate1": "4/30/2010","OrderID2": "A0000124", "OrderDate2": ""});

data _null_;
file j;

put &input_string;

run;

libname data json fileref=j;

data output;
 set data.root (drop=ordinal:);
run;

proc print data=output;
run;

sarahzhou_0-1641533374373.png

 

I read the document https://blogs.sas.com/content/sasdummy/2018/07/05/if-then-else-sas-programs/

It shoud give me the expected output.

 

Can you advise?

How can I modify my code.

Thank you!

 

ChrisHemedinger
Community Manager

Instead of using NRBQUOTE (which is used for masking values but doesn't produce a quoted string literal), simply use single quotes in the macro variable assignment.

 

filename j temp;

%let input_string ='{"OrderID1": "A0000123", "OrderDate1": "4/30/2010","OrderID2": "A0000124", "OrderDate2": ""}';

data _null_;
file j;

put &input_string;

run;

libname data json fileref=j;

data output;
 set data.root (drop=ordinal:);
run;

proc print data=output;
run;
Learn from the Experts! Check out the huge catalog of free sessions in the Ask the Expert webinar series.
sarahzhou
Quartz | Level 8
oh, I see now. Thanks!
sarahzhou
Quartz | Level 8

Hi,

The  input string does not controlled by my end , I have to follow the formate : %let input_string =%nrbquote([{"MEMBERID1": "A12345690", "DOB1": "", "MEMBERID2": "A12345677", "DOB2": "2022-Mar-03"}]);

then I tried to remove the square breaket by %sysfunc(compress(&input_string., "[]")) and it gives me error.

The updated script as below:

%let input_string =%nrbquote([{"MEMBERID1": "A12345690", "DOB1": "", "MEMBERID2": "A12345677", "DOB2": "2022-Mar-03"}]);

%let input_string_nb =%sysfunc(compress(&input_string., "[]"));
%put &input_string_nb.;
filename j temp;
data _null_;
file j;
put &input_string_nb.;
run;
libname data json fileref=j;

data output;
 set data.root (drop=ordinal:);
run;

proc print data=output noobs;
run;

How do I fix this?

Tom
Super User Tom
Super User

Why did you ask COMPRES() to remove the double quote character in addition to the open and close square bracket characters?  Take the two double quote characters out of the list of characters you want COMPRESS() to remove.

%let input_string_nb =%sysfunc(compress(&input_string.,[]));

You used the macro processor to generate an invalid PUT statement.  This is not valid SAS code.

put {"MEMBERID1": "A12345690", "DOB1": "", "MEMBERID2": "A12345677", "DOB2": "2022-Mar-03"};

If you are going to use the macro processor to generate SAS code you need to have it generate valid SAS code.

 

You will find it a lot easier to use normal SAS code to manipulate strings.  Plus in they case there is no need to remove the [ ] characters. In other cases removing them will destroy the JSON text.

%let input_string=
[{"MEMBERID1": "A12345690", "DOB1": "", "MEMBERID2": "A12345677", "DOB2": "2022-Mar-03"}]
;

filename json temp;
data _null_;
  file json;
  length string $32767;
  string=symget('input_string');
  put string ;
run;

libname json json fileref=json;

proc print data=json.root (drop=ordinal:) noobs;
run;

Results:

MEMBERID1    DOB1    MEMBERID2       DOB2

A12345690            A12345677    2022-Mar-03

 

sarahzhou
Quartz | Level 8

Hi, 

How can I call the MEMBERID1, DOB1,MEMBERID2, DOB2 for later use, I need to call DOB 1 and DOB 2 to do some logic comparation.

Thanks

Tom
Super User Tom
Super User

@sarahzhou wrote:

Hi, 

How can I call the MEMBERID1, DOB1,MEMBERID2, DOB2 for later use, I need to call DOB 1 and DOB 2 to do some logic comparation.

Thanks


I really have no idea what you are asking about.

 Now that you have data in a dataset just use normal SAS code to use it.  The same way you would use the values of NAME or AGE from SASHELP.CLASS. 

sarahzhou
Quartz | Level 8
Thank you.
Tom
Super User Tom
Super User

With simple regular strings like that I find that SCAN() is easier to use.

data test;
  json='[{"OrderID": "A0000123", "OrderDate": "4/30/2010"},{"OrderID": "A0000124", "OrderDate": ""}]';
  dlm='[]{}: ,';
  do index=1 to countw(json,dlm,'q');
    name=dequote(scan(json,index,dlm,'q'));
    index+1;
    value=dequote(scan(json,index,dlm,'q'));
    column+(name='OrderID');
    output;
  end;
  drop dlm index;
run;

proc print;
 by json ;
run;

Result

json=[{"OrderID": "A0000123", "OrderDate": "4/30/2010"},{"OrderID": "A0000124", "OrderDate": ""}]

Obs      name         value      column

 1     OrderID      A0000123        1
 2     OrderDate    4/30/2010       1
 3     OrderID      A0000124        2
 4     OrderDate                    2

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 13 replies
  • 2527 views
  • 5 likes
  • 3 in conversation