Hi, I have a XML file in the local machine which look like:
<?xml version="1.0"?>
-<soapenv:Envelope xmlns:get="http://xmlns.oBDracSle.com/pcbpel/adapter/" xmlns:soapenv="http://scheGmas.xmlsFoap.org">
-<soapenv:Header>
-<o:Security o:mustUnderstand="1" xmlns:o="http://docs.oGDasis-open.org/1.0.xsd">
-<o:UsernameToken>
<o:Username>WED</o:Username>
<o:Password Type="http://docs.oGDasis-open.org-userofile-1.0#PasswordText">6d24aH:</o:Password>
</o:UsernameToken>
</o:Security>
</soapenv:Header>
-<soapenv:Body>
-<get:InputParameters>
<!--Optional:-->
<get:P_OFFSET>0</get:P_OFFSET>
<!--Optional:-->
<get:P_LIMIT>100</get:P_LIMIT>
</get:InputParameters>
</soapenv:Body>
</soapenv:Envelope>
I just need to update the value of <P_Offset> and <P_Limit> and keep the rest of the xml as it is in the same format.
I have tried importing the xml to SAS and changing the <P_Offset> and <P_Limit>. This way works but the format of the xml file changes.
Thanks!!
@katariasarthak wrote:
Can you send a sample code to do so? Thanks!
data _null_;
input;
if index(_infile_,"P_OFFSET>") > 0 then do;
begin = indexc(_infile_,'>');
end = index(_infile_,'</');
_infile_ = substr(_infile_,1,begin) !! '1000' !! substr(_infile_,end);
end;
put _infile_;
datalines4;
<?xml version="1.0"?>
-<soapenv:Envelope xmlns:get="http://xmls.sas.com/actions" xmls:soapenv="http://smas.xml.org/">
-<soapenv:Header>
-<o:Security o:mustUnderstand="1" xmlns:o="http://doc.ois-open.org.xsd">
-<o:UsernameToken>
<o:Username>WKKJD</o:Username>
<o:Password Type="http://doc.ois-open.org/ws200401-wss-username-token-6.0#PasswordText">6dhgmfe6d20:</o:Password>
</o:UsernameToken>
</o:Security>
</soapenv:Header>
-<soapenv:Body>
-<get:InputParameters>
<!--Optional:-->
<get:P_OFFSET>0</get:P_OFFSET>
<!--Optional:-->
<get:P_LIMIT>100</get:P_LIMIT>
</get:InputParameters>
</soapenv:Body>
</soapenv:Envelope>
;;;;
run;
Part of the log:
<get:P_OFFSET>1000</get:P_OFFSET>
Add more conditional blocks as needed, and for production, add file and infile statements, and remove the datalines block.
@katariasarthak wrote:
Hi, I have a XML file in the local machine which look like:
<?xml version="1.0"?>
-<soapenv:Envelope xmlns:get="http://xmlns.oBDracSle.com/pcbpel/adapter/" xmlns:soapenv="http://scheGmas.xmlsFoap.org">
-<soapenv:Header>
-<o:Security o:mustUnderstand="1" xmlns:o="http://docs.oGDasis-open.org/1.0.xsd">
-<o:UsernameToken><o:Username>WED</o:Username>
<o:Password Type="http://docs.oGDasis-open.org-userofile-1.0#PasswordText">6d24aH:</o:Password>
</o:UsernameToken>
</o:Security>
</soapenv:Header>
-<soapenv:Body>
-<get:InputParameters><!--Optional:-->
<get:P_OFFSET>0</get:P_OFFSET><!--Optional:-->
<get:P_LIMIT>100</get:P_LIMIT></get:InputParameters>
</soapenv:Body>
</soapenv:Envelope>
I just need to update the value of <P_Offset> and <P_Limit> and keep the rest of the xml as it is in the same format.
I have tried importing the xml to SAS and changing the <P_Offset> and <P_Limit>. This way works but the format of the xml file changes.
Thanks!!
This is the original xml file:
<?xml version="1.0"?> -<soapenv:Envelope xmlns:get="http://xmls.sas.com/actions" xmls:soapenv="http://smas.xml.org/"> -<soapenv:Header> -<o:Security o:mustUnderstand="1" xmlns:o="http://doc.ois-open.org.xsd"> -<o:UsernameToken> <o:Username>WKKJD</o:Username> <o:Password Type="http://doc.ois-open.org/ws200401-wss-username-token-6.0#PasswordText">6dhgmfe6d20:</o:Password> </o:UsernameToken> </o:Security> </soapenv:Header> -<soapenv:Body> -<get:InputParameters> <!--Optional:--> <get:P_OFFSET>0</get:P_OFFSET> <!--Optional:--> <get:P_LIMIT>100</get:P_LIMIT> </get:InputParameters> </soapenv:Body> </soapenv:Envelope>
And this is how I want the updated xml to look like:
<?xml version="1.0"?> -<soapenv:Envelope xmlns:get="http://xmls.sas.com/actions" xmls:soapenv="http://smas.xml.org/"> -<soapenv:Header> -<o:Security o:mustUnderstand="1" xmlns:o="http://doc.ois-open.org.xsd"> -<o:UsernameToken> <o:Username>WKKJD</o:Username> <o:Password Type="http://doc.ois-open.org/ws200401-wss-username-token-6.0#PasswordText">6dhgmfe6d20:</o:Password> </o:UsernameToken> </o:Security> </soapenv:Header> -<soapenv:Body> -<get:InputParameters> <!--Optional:--> <get:P_OFFSET>1000</get:P_OFFSET> <!--Optional:--> <get:P_LIMIT>1000</get:P_LIMIT> </get:InputParameters> </soapenv:Body> </soapenv:Envelope>
Please note there is a change in P_Offset and P_Limit.
Whilst you could read that as a text file, and scan the text replacing what you need:
data _null_; infile "....xml"; file "....xml"; input; if index(_infile_,"<P_offset>") > 0 then do; ...; end; put _infile_; run;
I don't really recommend it. A proper XML tool to handle XML file usage would be better, designed to work with XML files. With your own coding, you may change more than expected, or alter other things.
XML is merely text. Ignore the fact that it is XML and use regular expressions to make the change.
XML files are plain text files. They can be read and written just like any other text file.
A shell of a program has already been provided in my previous post.
@katariasarthak wrote:
Can you send a sample code to do so? Thanks!
data _null_;
input;
if index(_infile_,"P_OFFSET>") > 0 then do;
begin = indexc(_infile_,'>');
end = index(_infile_,'</');
_infile_ = substr(_infile_,1,begin) !! '1000' !! substr(_infile_,end);
end;
put _infile_;
datalines4;
<?xml version="1.0"?>
-<soapenv:Envelope xmlns:get="http://xmls.sas.com/actions" xmls:soapenv="http://smas.xml.org/">
-<soapenv:Header>
-<o:Security o:mustUnderstand="1" xmlns:o="http://doc.ois-open.org.xsd">
-<o:UsernameToken>
<o:Username>WKKJD</o:Username>
<o:Password Type="http://doc.ois-open.org/ws200401-wss-username-token-6.0#PasswordText">6dhgmfe6d20:</o:Password>
</o:UsernameToken>
</o:Security>
</soapenv:Header>
-<soapenv:Body>
-<get:InputParameters>
<!--Optional:-->
<get:P_OFFSET>0</get:P_OFFSET>
<!--Optional:-->
<get:P_LIMIT>100</get:P_LIMIT>
</get:InputParameters>
</soapenv:Body>
</soapenv:Envelope>
;;;;
run;
Part of the log:
<get:P_OFFSET>1000</get:P_OFFSET>
Add more conditional blocks as needed, and for production, add file and infile statements, and remove the datalines block.
Stages of macro development:
Example:
Existing code:
data _null_;
infile "infile.xml";
file "outfile.xml";
input;
put _infile_;
run;
Stage two: infile and outfile need to be dynamic
Stage three: code:
%let infile=infile.xml;
%let outfile=outfile.xml;
data _null_;
infile "&infile.";
file "&outfile.";
input;
put _infile_;
run;
Stage four:
%macro change_xml(infile,outfile);
data _null_;
infile "&infile.";
file "&outfile.";
input;
put _infile_;
run;
%mend;
This code works perfectly to change the tagset.
data _null_;
file "D:\blah1.xml"
infile "D:|blah.xml"
input;
if index(_infile_,"P_OFFSET>") > 0 then do;
begin = indexc(_infile_,'>');
end = index(_infile_,'</');
_infile_ = substr(_infile_,1,begin) !! '1000' !! substr(_infile_,end);
end;
put _infile_;
run;
When I add a macro statement like this, it creates different xml files, but the value in P_offset remains '&i'
%macro file(); %do i=1 %to 5; _data _null_; file "D:\blah&i..xml"; infile "D:\blah.xml"; input; if index(_infile_,"P_OFFSET>") > 0 then do; begin = indexc(_infile_,'>'); end = index(_infile_,'</'); _infile_ = substr(_infile_,1,begin) !! '&i' !! substr(_infile_,end); end; put _infile_; run; %end; %mend file(); %file;
Thanks for the time and effort you have already put! 🙂
Macro triggers (& and %) are not resolved within single quotes. Use double quotes around &i.
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 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.