Help using Base SAS procedures

Using proc matadata, macro variable in XMLSelect

Accepted Solution Solved
Reply
New Contributor
Posts: 2
Accepted Solution

Using proc matadata, macro variable in XMLSelect

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. 


Accepted Solutions
Solution
‎04-20-2017 08:46 AM
SAS Super FREQ
Posts: 683

Re: Using proc matadata, macro variable in XMLSelect

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


All Replies
Solution
‎04-20-2017 08:46 AM
SAS Super FREQ
Posts: 683

Re: Using proc matadata, macro variable in XMLSelect

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

New Contributor
Posts: 2

Re: Using proc matadata, macro variable in XMLSelect

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.

SAS Super FREQ
Posts: 683

Re: Using proc matadata, macro variable in XMLSelect

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
 
Super User
Posts: 5,081

Re: Using proc matadata, macro variable in XMLSelect

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.%'));

 

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 4 replies
  • 149 views
  • 1 like
  • 3 in conversation