2
votes

Consider the following sas code fragment:

%macro temp(querystr=);
  filename request temp;

  data _null_;
    file request;

    put "<string>&querystr</string>";
  run;
%mend temp;

%temp(querystr="term 1" and "term2");

Note that this piece of code will not compile because the first quote in querystr will close the starting quote of the put statement when the compiler replaces querystr in the data step.

I would like to mask the quotes in the query string to transform it to a valid xml fragment, like:

<string>&quot;term 1&quot; and &quot;term 2&quot;</string>

Is there a way to output the above line to the file with proper masking of the quotation marks? I tried the %sysfunc(TranWrd()) function in combination with masking functions like %nrbquote() etc but so far I haven't found a working solution. Any help is appreciated!

4

4 Answers

3
votes

Add a htmlencode with 'quot' option to the datastep and use %bquote to mask the quotes until macro execution.

%macro temp(querystr=);

  filename request temp;

  data _null_;

    file request;

    string = cats('<string>',htmlencode("&querystr",' quot'),'</string>');

    put string;

  run;

%mend temp;

%temp(querystr=%bquote("term 1" and "term2"));
2
votes

As long as the double quotes are balanced, macro is invoked fine. So, you don't need to impose on macro users to macro quote the parameter. Your macro can do this for them as below.

   %macro temp(querystr=);
     filename request temp;
     data _null_;
       file request;
       s = catx(htmlencode("%superq(querystr)","quot"),"<string>","</string>");
       l = length(s);
       put s $varying. l;
     run;
   %mend temp;

   %temp(querystr="term 1" and "term2");

   /* check */
   data _null_;
     infile request;
     input;
     put _infile_;
   run;
   /* on log
   <string>&quot;term 1&quot; and &quot;term2&quot;</string>
   */ 
1
votes

Try the following:

options mcompilenote=all;
%macro temp(querystr=); 
  filename request temp; 

  data _null_; 
    file request; 
    querystr=symget('querystr');
    querystr=htmlencode(querystr,'quot');
    *putlog querystr $;
    string="<string>"!!trim(querystr)!!"</string>";
    put string $200.;
    *put "<string>&querystr</string>"; 
  run; 
%mend temp; 

%temp(querystr="term 1" and "term2"); 
-1
votes

Just use put 'foo'; instead:

%macro temp(querystr=);
  filename request temp;

  data _null_;
    file request;

    put '<string>&querystr</string>';
  run;
%mend temp;

%temp(querystr="term 1" and "term2");