Investigate the SAS ODS parameter option PROTECTSPECIALCHARS= for what you are asking. The option is mentioned in the SAS technical paper, found on the SAS support website http://support.sas.com/ if interested.
Scott may be right about protectspecialchars but your code has some other issues:
1) *ProcessBody; is a COMMENT. For stored processes, it is a required comment that causes parameters to be initialized correctly. If your program is not using parameters, that's not a big deal, but without a semi-colon, your comment does not end until the semicolon for %stpbegin. The '*ProcessBody;" line must end with a semi-colon (Hopefully, the typo in your code is not in the actual program)
2) data _null_; (not data null) underscore NULL underscore -- _NULL_ is a special syntax that allows you to use data step programming syntax without creating a SAS dataset. This is not a deal breaker, just an observation, it would not cause your program to error. You'd just create work.null on the server.
3) you don't have a FILEREF for the PUT statement. Actually this is the part of the program that bothers me the most. Generally, you would have FILE PRINT (in Display Manager for LISTING) or FILE 'XYZ.HTML' (if you were NOT using ODS) or FILE _WEBOUT; (if you were writing an HTTP stream). Here are some examples. http://support.sas.com/kb/18/969.html http://support.sas.com/kb/30/889.html
4) But, I remember there is some issue with DATA _NULL_ and PUT statements inside stored processes. http://support.sas.com/kb/13/599.html (don't use %stpbegin/%stpend)
from here: http://support.sas.com/rnd/itech/doc9/dev_guide/stprocess/inet2stp.html
look for the bullet point (and example) that starts:
If you are writing to _WEBOUT using PUT statements while ODS has _WEBOUT open, when you execute the code the PUT statement data might be out of sequence with the data generated by ODS. This problem occurs because both your code and ODS are opening the same fileref at the same time. For example, the following code might not always work as expected: (example follows)
5) Do you really want to write out a separate TABLE for EVERY observation???? generally when writing HTML tags on your own, you write the <TABLE> tag one time, then write something for every obs and then write the close tag when the end of the file is reached.
You may want to consider looking at the stored process doc and the samples of writing your own HTML. If you invoke the Stored Process Web Application, there are some canned samples that you can look at which may help you. You might also consider contacing SAS Tech Support for more help.
I'll try to keep this succinct. The issue is not protectspecialchars. You can look at the Hello World stored process by searching for stored processes in the Portal search facility and if the samples were installed (they usually are), you can execute the SP and remember to select that you get the SAS Log.
You can show the SAS log after Hello World SP runs & you'll see that you don't actually need to use %stpbegin with this kind of SP.
Consider these 2 different SPs:
1) in the Foundation repository STP_Orion, I have the following SP stp_proc_print
title '<h1>My Title</h1>';
proc print data=sashelp.class(obs=3) OBS='ID';
var Name Age Height;
ods &_odsdest text='<div><H2 align="center">This is the End. This is the End, My Friend</H2></div>';
The highlights of this SP are that the %stpbegin controls all the "wrapper" HTML results that will be created, I'm increasing the size of the title and adding an H2 tag at the bottom of the output using ODS TEXT= capability by using HTML tags directly in my code. No problems with the < or the > .
2) Then there's a second SP where I control all the HTML that's written out. It's also in the Foundation repository STP_Orion, named put_stmt_webout
set sashelp.class end=eof;
if _n_ = 1 then do;
put '<head><title>PUT Stmt</title></head>';
put '<h1 align="center">My Title</h1>';
put '<table border="1" align="center">';
if _n_ le 3 then do;
if eof=1 then do;
put '<h2 align="center">This is the End</h2>';
Either #1 or #2 run successfully when submitted from the Information Delivery Portal. However, as soon as I add %stpbegin/%stpend to #2, it fails because the _webout is "grabbed" for use by the %stpbegin setup (the non-technical explanation).