These two "$args->{zip} and $args->{phone}" will give me warnings on "use of uninitialized value" because I am not passing them.
Actually, that's not true. Perl doesn't care if you pass them or not. You are getting the warnings because you are attempting to use them. It's an important distinction. As has been pointed out, you can use exists(). That'll tell you if the key is in the hash... you might also consider defined(). If you want an empty tag or a default (rather than no tag) when the data doesn't exists, you can use a conditional operator...
print '<zip>' . (defined($args->{zip}) ? $args->{zip} : "DEFAULT") . '
+</zip>';
-sauoq
"My two cents aren't worth a dime.";