The really interesting part of this example is the page source code, as shown in Example 3.18. The following section explains how to create XHTML (or any other markup) using a custom tagset and ODS.
Example 3.18 XHTML Source
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SAS Output</title>
</head>
<body>
<h1>Retail Sales In Millions Of $</h1>
<table border="1">
<thead>
<tr>
<th>Year</th><th>Total Sales</th>
<th>Overall Percent</th>
<th>Number of Sales</th>
<th>Average Sale</th><th>Smallest Sale</th>
<th>Largest Sale</th>
</tr>
</thead>
<tbody>
<tr>
<th> 1994</th>
<td> $1,874</td>
<td> 5.97</td>
<td> 2</td>
<td> $937.00</td>
<td> $876</td>
<td> $998</td>
</tr>
[... repeated lines omitted ...]
<tr>
<th> 1980</th>
<td> $1,030</td>
<td> 3.28</td>
<td> 4</td>
<td> $257.50</td>
<td> $220</td>
<td> $295</td>
</tr>
<tr>
<th>Total</th>
<td> $31,374</td>
<td> 100.00</td>
<td> 58</td>
<td> $540.93</td>
<td> $220</td>
<td> $998</td>
</tr>
</tbody>
</table>
<p>
<a href="http://validator.w3.org/check/referer">
Chapter 3 Creating Static HTML Output 67
<img src="http://www.w3.org/Icons/valid-xhtml11"
alt="Valid XHTML 1.1!" height="31" width="88" /></a>
</p>
</body>
</html>
PROC TEMPLATE: Not Just for Geeks Anymore
As noted previously, the item store contains templates for tables and styles. It also contains the tagsets used for the ODS MARKUP statement. SAS supplies a simple XHTML template, or you can create your own by running the following program:
Example 3.19 XHTML Template
proc template;
define tagset Tagsets.xhtml / store = SASUSER.TEMPLAT;
define event cell_is_empty;
put %nrstr(" ");
end;
define event doc;
start:
put "<?xml version=""1.0"" encoding=""UTF-8""?>" NL;
put "<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.1//EN""" NL;
put """http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd"">" NL;
put "<html xmlns=""http://www.w3.org/1999/xhtml"">" NL;
ndent;
finish:
xdent;
put "</html>" NL;
end;
define event doc_head;
start:
put "<head>" NL;
ndent;
finish:
xdent;
put "</head>" NL;
end;
define event doc_body;
start:
put "<body>" NL;
put TITLE;
finish:
/* add W3C logo to page */
put '<p>' NL;
put '<a href="http://validator.w3.org/check/referer">' NL;
put '<img src="http://www.w3.org/Icons/valid-xhtml11"' NL;
put 'alt="Valid XHTML 1.1!" height="31" width="88" /></a>' NL;
put '</p>' NL;
put '</body>' NL;
end;
define event doc_title;
put "<title>";
put "SAS Output" / if !exists(VALUE);
put VALUE;
put "</title>" NL;
end;
define event proc_title;
put "<h2>" VALUE "</h2>" CR;
end;
define event system_title;
put "<h1>" VALUE "</h1>" CR;
end;
define event system_footer;
put "<h1>" VALUE "</h1>" CR;
end;
define event byline;
put "<h2>" VALUE "</h2>" CR;
end;
define event note;
put "<h3>" VALUE "</h3>" CR;
end;
define event fatal;
put "<h3>" VALUE "</h3>" CR;
end;
define event error;
put "<h3>" VALUE "</h3>" CR;
end;
define event warning;
put "<h3>" VALUE "</h3>" CR;
end;
define event table;
start:
put "<table border=""1"">" NL;
ndent;
finish:
xdent;
put "</table>" NL;
end;
define event row;
start:
put "<tr>" NL;
ndent;
finish:
xdent;
put "</tr>" NL;
end;
define event table_head;
start:
Chapter 3 Creating Static HTML Output 69
put "<thead>" NL;
ndent;
finish:
xdent;
put "</thead>" NL;
end;
define event table_body;
start:
put "<tbody>" NL;
ndent;
finish:
xdent;
put "</tbody>" NL;
end;
define event table_foot;
start:
put "<tfoot>" NL;
ndent;
finish:
xdent;
put "</tfoot>" NL;
end;
define event rowcol;
putq " rowspan=" ROWSPAN;
putq " colspan=" COLSPAN;
end;
define event header;
start:
put "<th";
trigger rowcol;
put ">";
put VALUE;
finish:
put "</th>";
end;
define event data;
start:
put "<th" / if cmp( section , "head" );
put "<td" / if !cmp( section , "head" );
trigger rowcol;
put ">";
put VALUE;
finish:
put "</th>" NL / if cmp( section , "head" );
put "</td>" NL / if !cmp( section , "head" );
end;
mapsub = %nrstr("/</>/&/"/");
map = %nrstr("<>&""");
split = "<br />";
output_type = "xml";
indent = 3;
end; /* define tagset */
PROC TEMPLATE listings can be intimidating, and many otherwise brave SAS users have avoided this procedure because of its reputation for complexity. No worries mate! It is just a question of putting together simple elements, as the preceding example illustrates.
There is a DEFINE statement for each event in the ODS output (shown in bold in the example) that describes what to do in that case. Consider the following extract:
define event doc_head;
start:
put "<head>" NL;
ndent;
finish:
xdent;
put "</head>" NL;
end;
All this says is that when ODS gets to the top of the document, it should write out a header. At the start of the header, put the opening tag <head>. After writing the initial tag, insert a line break and then indent. At the finish, stop indenting, put the closing tag </head>, and then put in a line break. See, that's not so hard!
In any case, pasting this code into the SAS editor window and submitting it should result in the following log message:
NOTE: TAGSET 'Tagsets.Xhtml' has been saved to: SASUSER.TEMPLAT
You should also see a new tagset called XHTML in SASUSER.TEMPLAT in the Templates window (see Display 3.10). You can now run Example 3.18 to get the result shown previously.
In conclusion, XHTML is an alternative to HTML for data display when used with custom stylesheets to create a formatted document in the client’s browser. Using ODS, it is possible to customize your output for almost any conceivable application. Thus far, however, we have only considered static HTML output. In the chapters that follow, the much more interesting (and complex) topic of dynamic Web pages will be considered.
References
SAS Training
URL references are current as of the date of publication.
SAS Institute Inc. Advanced Output Delivery System Topics (Course Notes). Cary, NC:
SAS Institute Inc. http://support.sas.com/training/us/crs/odsadv9.html.
Chapter 3 Creating Static HTML Output 71
SAS Institute Inc. The Complete Guide to the SAS Output Delivery System. Cary, NC:
SAS Institute Inc. http://support.sas.com/rnd/base/early- access/odsdoc2/sashtml/tw5195/index.htm.
SAS Institute Inc. Creating Markup Language Files Using ODS Markup, SAS XML Libname Engine, and the TEMPLATE Procedure (Course Notes). Cary, NC: SAS Institute Inc. http://support.sas.com/training/us/crs/lwxml.html.
SAS Institute Inc. Getting Started with the Output Delivery System Topics (Course Notes). Cary, NC: SAS Institute Inc. http://support.sas.com/training/us/crs/odsgs.html.
SAS Institute Inc. Using the Output Delivery System to Create XML Files (Course Notes). Cary, NC: SAS Institute Inc. http://support.sas.com/training/us/crs/odsxml.html.
SAS Publications
Barlow, Todd. 2002. “Designing Web Applications: Lessons from SAS User Interface Analysts.” Proceedings of the Twenty-Seventh Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Bessler, LeRoy. 2002. “Inform and Influence with Image and Data: Communication- effective Web Design for ODS, SAS, and SAS/GRAPH.” Proceedings of the Twenty- Seventh Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Bessler, LeRoy. 2003. “Web Communication Effectiveness: Design and Methods to Get the Best Out of ODS, SAS, and SAS/GRAPH.” Proceedings of the Twenty-Eight Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Bessler, LeRoy and Francesca Pierri. “Show Your Graphs and Tables at Their Best on the Web with ODS.” Proceedings of the Twenty-Seventh Annual SAS Users Group
International Conference. Cary, NC: SAS Institute Inc.
Carpenter, Art. 2002. Carpenter's Complete Guide to the SAS Macro Language. 2nd ed.
Cary, NC: SAS Institute Inc.
Gilbert, Jeffery D. 2005. “Web Reporting Using the ODS.” Proceedings of the Thirtieth Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Gupta, Sunil K. 2003. Quick Results with the Output Delivery System (Art Carpenter’s SAS Software Series). Cary, NC: SAS Institute Inc.
Gupta, Sunil K. 2001. “Using Styles and Templates to Customize SAS ODS Output.”
Proceedings of the Twenty-Sixth Annual SASUsers Group International Conference.
Cary, NC: SAS Institute Inc.
Haworth, Lauren E. 2001. Output Delivery System: The Basics. Cary, NC: SAS Institute Inc.
Haworth, Lauren E. 1999. PROC TABULATE By Example. Cary, NC: SAS Institute Inc.
Johnson, Bernadette. 2003. Instant ODS: Style Templates for the SAS Output Delivery System. Cary, NC: SAS Institute Inc.
Lafler, Kirk Paul. 2002. “Output Delivery Goes Web.” Proceedings of the Twenty- Seventh Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Morgan, Derek and Steve Hoffner. 2004. “Generating a Detailed Table of Contents for Web-Served Output.” Proceedings of the Twenty-Ninth Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Newkirk, Gregory. 2004. “Using ODS, an Easy Approach in Creating HTML Web Pages.” Proceedings of the Twenty-Ninth Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Olinger, Chris. 2000. “ODS for Dummies.” Proceedings of the Twenty-Fifth Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Olinger, Chris. 2005. “A Sample Web-Based Reporting Container for ODS XML Reports.” Proceedings of the Thirtieth Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Olinger, Chris. 1999.“Twisty Little Passages, All Alike – ODS Templates Exposed.”
Proceedings of the Twenty-Fourth Annual SAS Users Group International Conference.
Cary, NC: SAS Institute Inc.
Pratter, Frederick. 2001. “Beyond HTML: Using the SAS System Version 8.2 With XML.” Proceedings of the Twenty-Sixth Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Rafiee, Dana and Stan Andermann. 2001. “Simple Ways to Publish Reports and Graphs on the Web.” Proceedings of the Twenty-Sixth Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Smith, Curtis A. 2002. “Web Enabling Your Graphs With HTML, ActiveX, and Java Using SAS/GRAPH and the Output Delivery System.” Proceedings of the Twenty- Seventh Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc.
Links
Creating Customized Tagsets to Use with ODS and XML LIBNAME Engine – http://support.sas.com/rnd/base/topics/odsmarkup/tagsets.html
Extensible Markup Language – http://www.w3.org/TR/REC-xml.html
HTML Data Set Formatter Syntax Reference –
http://support.sas.com/rnd/web/intrnet/format/ds/dssyn.html
HTML Formatting Tools – http://support.sas.com/rnd/web/intrnet/format/
HTML Output Formatter Syntax Reference –
http://support.sas.com/rnd/web/intrnet/format/out/outsyn.html
HTML Tabulate Formatter Syntax Reference –
http://support.sas.com/rnd/web/intrnet/format/tab/tabsyn.html
Output Delivery System – http://support.sas.com/rnd/base/index-ods-resources.html
PROC TEMPLATE FAQ –
http://support.sas.com/rnd/base/topics/templateFAQ/Template.html
Using ODS to Export Output in a Markup Language – http://support.sas.com/rnd/base/topics/odsmarkup/
XHTML – http://www.w3.org/TR/2001/REC-xhtml11-20010531
P a r t 2
Access to SAS with SAS/IntrNet Software
Chapter 4 Remote Access to SAS 75
Chapter 5 Web Applications Programming 91
Chapter 6 SAS/IntrNet: the Application Dispatcher 101 Chapter 7 SAS/IntrNet: htmSQL 127
C h a p t e r 4
Remote Access to SAS
Client/Server Computing 75
Remote Data Services with SAS/SHARE 77 Editing the TCP Services File 77
Configuring TCP Security 78
Starting and Stopping the SAS/SHARE Server 79 Managing SAS/SHARE as a Windows Service 81 SAS AppDev Studio Service Manager 83
Managing Servers with SAS Management Console 83 Access to Remote Library Services 84
Remote SQL Pass-Through (RSPT) 85
Remote Compute Services with SAS/CONNECT 86