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.
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
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
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.
hi
first use single quotes and then use the appropriate flags.
from the doc
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.%'));
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.