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

Hello, 

 

I have problem with using proc matadata in macro. 

%let metaserver=xxx;
%let metaport= xxx;
%let metauser= xxx;
%let metapass= xxx;

options metaserver="&metaserver."
	metaport=&metaport.
	metauser="&metauser."
	metapass="&metapass.";

options noquotelenmax;

%macro testmacro(_admin_grp =);
	
filename resp "/tmp/metafile.xml";
%let test=%str(%'&_admin_grp.%');
%put &test;
proc metadata 
	in='<GetMetadataObjects>
	<Reposid>$METAREPOSITORY</Reposid>
	<Type>Person</Type>
	<Objects/>
	<NS>SAS</NS>
	<Flags>900</Flags>
	<Options>
	<Templates>  
		<Person Name=""> <IdentityGroups/> </Person>  
	</Templates>
	<XMLSelect search="*[not(IdentityGroups/IdentityGroup[@Name = '&test'])]"/>
	</Options>
	</GetMetadataObjects>'
	out=resp;
run;


filename mapa temp;
data _null_;
	file mapa;
	put '<?xml version="1.0" encoding="windows-1250"?> ';
	put ' <SXLEMAP version="1.2">';
	put '   <!-- ############################################################ -->';
	put '   <TABLE description="Type" name="USERS">';
	put '       <TABLE-PATH syntax="XPath">/GetMetadataObjects/Objects/Person</TABLE-PATH>';
	put '	<COLUMN name="Name">';
	put '           <PATH syntax="XPath">/GetMetadataObjects/Objects/Person/@Name</PATH>';
	put '          <TYPE>character</TYPE>';
	put '           <DATATYPE>string</DATATYPE>';
	put '           <LENGTH>100</LENGTH>';
	put '       </COLUMN>';
	put '    </TABLE>';
	put ' </SXLEMAP>';
run;

libname   resp xml xmlmap=mapa;

data users;
	set resp.users;
run;
%mend;


%testmacro(
	_admin_grp = ADMIN
	);

Log Errors:: 

SYMBOLGEN: Makro Variable TEST resolved to 'ADMIN'

NOTE: Line generated by the macro variable "TEST".
89 (IdentityGroups/IdentityGroup[@Name = ''ADMIN'
_
22
_
200
MPRINT(TESTMACRO): proc metadata
in='<GetMetadataObjects> <Reposid>$METAREPOSITORY</Reposid> <Type>Person</Type> <Objects/> <NS>SAS</NS> <Flags>900</Flags> <Options>
<Templates> <Person Name=""> <IdentityGroups/> </Person> </Templates> <XMLSelect

search="*[not(IdentityGroups/IdentityGroup[@Name = ''ADMIN''])]"/> </Options> </GetMetadataObjects>' out=resp;
MPRINT(TESTMACRO): run;

ERROR 22-322: Syntax error, expecting one of the following: ;, HEADER, HOST, ID, IN, INSUREMACHINE, IPADDR, MACHINE,
METADATASERVER, METAID, METAPASS, METAPORT, METAPROTOCOL, METAREPOSITORY, METASERVER, METAUSER, METHOD, OUT,
PASSWORD, PORT, PROTOCOL, PW, REPOS, REPOSITORY, SERVER, USER, USERID, VERBOSE.

ERROR 200-322: The symbol is not recognized and will be ignored.

 

This code works:

%let metaserver=xxx;
%let metaport= xxx;
%let metauser= xxx;
%let metapass= xxx;

options metaserver="&metaserver."
	metaport=&metaport.
	metauser="&metauser."
	metapass="&metapass.";

options noquotelenmax;

%macro testmacro(_admin_grp =);
	
filename resp "/tmp/metafile.xml";
%let test=%str(%'&_admin_grp.%');
%put &test;
proc metadata 
	in='<GetMetadataObjects>
	<Reposid>$METAREPOSITORY</Reposid>
	<Type>Person</Type>
	<Objects/>
	<NS>SAS</NS>
	<Flags>900</Flags>
	<Options>
	<Templates>  
		<Person Name=""> <IdentityGroups/> </Person>  
	</Templates>
	<XMLSelect search="*[not(IdentityGroups/IdentityGroup[@Name = ''ADMIN''])]"/>
	</Options>
	</GetMetadataObjects>'
	out=resp;
run;


filename mapa temp;
data _null_;
	file mapa;
	put '<?xml version="1.0" encoding="windows-1250"?> ';
	put ' <SXLEMAP version="1.2">';
	put '   <!-- ############################################################ -->';
	put '   <TABLE description="Type" name="USERS">';
	put '       <TABLE-PATH syntax="XPath">/GetMetadataObjects/Objects/Person</TABLE-PATH>';
	put '	<COLUMN name="Name">';
	put '           <PATH syntax="XPath">/GetMetadataObjects/Objects/Person/@Name</PATH>';
	put '          <TYPE>character</TYPE>';
	put '           <DATATYPE>string</DATATYPE>';
	put '           <LENGTH>100</LENGTH>';
	put '       </COLUMN>';
	put '    </TABLE>';
	put ' </SXLEMAP>';
run;

libname   resp xml xmlmap=mapa;

data users;
	set resp.users;
run;
%mend;


%testmacro(
	_admin_grp = ADMIN
	);

but I need use macro variable in XMLSelect. 

1 ACCEPTED SOLUTION

Accepted Solutions
BrunoMueller
SAS Super FREQ

Hi

 

Macro triggers are only resolved when the string is within double quotes. So your code has to start with

Proc Metadata
  in=" sometext ";
run;

So your code can look like this:

%let publicType = Folder;
proc metadata
  in="
<GetMetadataObjects>
  <Reposid>$METAREPOSITORY</Reposid>

   <Type>Root</Type>
   <Objects/>
   <NS>SAS</NS>
   <!-- Specify the OMI_XMLSELECT (128) flag  -->
   <Flags>128</Flags>
   <Options>
      <!-- get private user folders -->
      <XMLSELECT search=""Tree[@PublicType='&publicType'][AssociatedIdentity/Person]""/>
   </Options>
</GetMetadataObjects>
"
;
run;

Please note, since the '&publicType' is within some other double quotes the macro trigger is resolved.

 

Also note we need to have two double quotes at the beginning and end of the <XMLSELECT search=

 

Another way of doing this, would be to write the XML into a file, this gives you alot more control and also allows to read SAS data sets and build your XML.

 

Here is an example that reads the text from within the code and uses the RESOLVE function to resolve macro triggers.

 

%let publicType = Folder;
filename mdxml temp;


data want;
  infile cards truncover;
  input line $1024.;
  line2 = resolve(line);
  file mdxml;
  put line2;
cards4;
<GetMetadataObjects>
  <Reposid>$METAREPOSITORY</Reposid>

   <Type>Root</Type>
   <Objects/>
   <NS>SAS</NS>
   <!-- Specify the OMI_XMLSELECT (128) flag  -->
   <Flags>128</Flags>
   <Options>
      <!-- get private user folders -->
      <XMLSELECT search="Tree[@PublicType='&publicType'][AssociatedIdentity/Person]"/>
   </Options>
</GetMetadataObjects>
;;;;

proc metadata
  in=mdxml
;
run;

Bruno

View solution in original post

4 REPLIES 4
BrunoMueller
SAS Super FREQ

Hi

 

Macro triggers are only resolved when the string is within double quotes. So your code has to start with

Proc Metadata
  in=" sometext ";
run;

So your code can look like this:

%let publicType = Folder;
proc metadata
  in="
<GetMetadataObjects>
  <Reposid>$METAREPOSITORY</Reposid>

   <Type>Root</Type>
   <Objects/>
   <NS>SAS</NS>
   <!-- Specify the OMI_XMLSELECT (128) flag  -->
   <Flags>128</Flags>
   <Options>
      <!-- get private user folders -->
      <XMLSELECT search=""Tree[@PublicType='&publicType'][AssociatedIdentity/Person]""/>
   </Options>
</GetMetadataObjects>
"
;
run;

Please note, since the '&publicType' is within some other double quotes the macro trigger is resolved.

 

Also note we need to have two double quotes at the beginning and end of the <XMLSELECT search=

 

Another way of doing this, would be to write the XML into a file, this gives you alot more control and also allows to read SAS data sets and build your XML.

 

Here is an example that reads the text from within the code and uses the RESOLVE function to resolve macro triggers.

 

%let publicType = Folder;
filename mdxml temp;


data want;
  infile cards truncover;
  input line $1024.;
  line2 = resolve(line);
  file mdxml;
  put line2;
cards4;
<GetMetadataObjects>
  <Reposid>$METAREPOSITORY</Reposid>

   <Type>Root</Type>
   <Objects/>
   <NS>SAS</NS>
   <!-- Specify the OMI_XMLSELECT (128) flag  -->
   <Flags>128</Flags>
   <Options>
      <!-- get private user folders -->
      <XMLSELECT search="Tree[@PublicType='&publicType'][AssociatedIdentity/Person]"/>
   </Options>
</GetMetadataObjects>
;;;;

proc metadata
  in=mdxml
;
run;

Bruno

mmstudent
Calcite | Level 5

Thanks Bruno. 

But now how can I add:  

<Templates>
<IdentityGroup Id="" Name="" DisplayName=""> <MemberIdentities/></IdentityGroup>
<IdentityGroup Id="" Name=""/>
</Templates>

I tried use single quotes and change Flags values. 

In xml file I have only variables used in XMLSelect.

BrunoMueller
SAS Super FREQ

hi

 

first use single quotes and then use the appropriate flags.

 

from the doc

Specifying OMI_GET_METADATA and Other GetMetadata Flags

To specify a GetMetadata flag in a GetMetadataObjects request, add the flag’s value to the OMI_GET_METADATA flag and to any other GetMetadataObjects flags that you have set. For example, if OMI_XMLSELECT (128) is already set, and you want to specify OMI_GET_METADATA (256) and OMI_ALL_SIMPLE (8) to get all of the attributes of each object, add their values together (128+256+8=392) and specify the sum in the FLAGS parameter.
 
So if you use <Flags>392</Flags> you will get all the attributes for the type specified in <Type/>
 
It will be best to have a look at the doc SAS(R) 9.4 Open Metadata Interface: Reference and Usage
 
Bruno
 
Astounding
PROC Star

I can't test this, but it's possible that this line is causing the problem:

 

%let test=%str(%'&_admin_grp.%');

 

It's possible that SAS isn't unquoting the single quotes in time.  If that's the source of the problem you can overcome it by switching to:

 

%let test=%unquote(%str(%'&_admin_grp.%'));

 

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!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 4 replies
  • 1432 views
  • 1 like
  • 3 in conversation