The way you had written most of your original code is a separate PUT statement for each line written to the file. What most of the answers have suggested you do is add conditional logic to execute a different PUT statement depending on the value of the variable in question.
The proposed solutions are very simple applications on conditional logic. IF/THEN/ELSE.
What is it that you are having trouble with understanding?
Do you not know how to write that type of logic? The basic structure is this:
if condition then <statement1>;
else <statement2>;
If you need to execute multiple statements then add DO/END blocks like this.
if condition then do;
<statement1 A>;
<statement1 B>;
end;
else do;
<statement2 A>;
<statement2 B>;
end;
Or do you not understand what the PUT statements in the <then> and <else> blocks are doing?
I understand how the if then statement works and also how put statement works. But it is unfortunate I'm not not getting the desired output even after applying the proposed solution. I believe I have to place the if then else part at the right step (which I have trouble to locate it) to get rid of the issue.
Create fully working example for one observation. That means post a data step with in-line data to create your example data.
data have;
length var1 $20 var2 8;
infile cards dsd dlm='|' truncover ;
input var1 var2;
cards;
XXX|123
;
A data step to create the XML output for that observation.
data _null_;
set have ;
file 'example.xml' ;
put ....
run;
The resulting XML you get when you run that code.
<tag1>XXX</tag1>
And what you want to get instead and explanation of how the two outputs differ.
Perhaps the issue is that you do not understand either the input data or the output format and it is causing you to use the wrong condition in your IF statement?
Include the LOG from running the step that writes the XML. Including any notes like uninitialized variables, conversion from character to numeric.
One simple mistake could be is that you think the variable is numeric but it is really character and somewhere earlier in your process a missing value got assigned to the variable and it is stored as ' .' and so it is not a missing character value and is thus getting written to your output file.
73 data _null_; 74 do x=1, . ; 75 length y $5 ; 76 y=x; 77 put x= y=:$quote. ; 78 end; 79 run; NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column). 76:8 x=1 y=" 1" x=. y=" ."
Of course you are getting two lines. You have two PUT statements. One unconditional and then a second that only writes when the value is not missing. So change:
put ' <dynamicPricingFactor>' dpf_base +(-1) '</dynamicPricingFactor>';
if dpf_base eq . then do;
put ' <dynamicPricingFactor></dynamicPricingFactor>';
end;
to something like
if missing (dpf_base) then do;
put ' <dynamicPricingFactor></dynamicPricingFactor>';
end;
else do;
put ' <dynamicPricingFactor>' dpf_base +(-1) '</dynamicPricingFactor>';
end;
Note that for most XML uses you can use an abbreviated syntax in the XML file for the empty tags. Like this:
put ' <dynamicPricingFactor />';
Hi,
Risking repetting other users advise, ckeck your code, specifically this first part:
put ' <dynamicPricingFactor>' dpf_base +(-1) '</dynamicPricingFactor>';
if dpf_base eq . then do;
put ' <dynamicPricingFactor></dynamicPricingFactor>';
end;
What is happening here?
Whenever dpf_base is "." or not the first put statement always "prints" this first line: <dynamicPricingFactor> </dynamicPricingFactor>. But when dpf_base is eq "." then your if condition is true and a second line <dynamicPricingFactor></dynamicPricingFactor> is printed too. That's why you end up with two <dynamicPricingFactor> </dynamicPricingFactor> statements.
What you have to do is then remove the first put and use the if else statement proposed earlier. That way only one <dynamicPricingFactor> </dynamicPricingFactor> will be "printed". Better yet use the solution proposed by Patrick:
move= -1-missing(dpf_base);
put ' <dynamicPricingFactor>' dpf_base +move '</dynamicPricingFactor>';
This solution is actually very cleaver and its easier to read this way (my opinion). When i first see your post i actually thougth that you were lookink for something like this. But didn't know this approach.
I'm not sure that i'm helping you but your code should look like this:
options missing="";
move= -1-missing(dpf_base);
put ' <dynamicPricingFactor>' dpf_base +move '</dynamicPricingFactor>';
put ' <dynamicPricingFactorPolicyCoverLangList>';
put ' <dynamicPricingFactorPolicyCoverLang>';
put ' <languageRef>';
put ' <externalIdentifier>FR</externalIdentifier>';
put ' </languageRef>';
a=translate(expl_base,'-','/');
put ' <explanation>' a '</explanation>';
put ' </dynamicPricingFactorPolicyCoverLang>';
put ' <dynamicPricingFactorPolicyCoverLang>';
put ' <languageRef>';
put ' <externalIdentifier>VLS</externalIdentifier>';
put ' </languageRef>';
put ' <explanation>' a '</explanation>';
*put ' <explanation>' translate(expl_base,'-','/') '</explanation>';
put ' </dynamicPricingFactorPolicyCoverLang>';
put ' </dynamicPricingFactorPolicyCoverLangList>';
put ' </dynamicPricingFactorPolicyCover>';
put '<dynamicPricingFactorPolicyCover>';
put '<productVersionCoverRef>';
put ' <externalIdentifier>' cover +(-1) '</externalIdentifier>';
put ' </productVersionCoverRef>';
put ' <isForNonMatch>true</isForNonMatch>';
put ' <hashCode1>' veh_driver_hashcode +(-1) '</hashCode1>';
put ' <hashCode2></hashCode2>';
Best Regards,
João Moreira
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.