Previous Page | Next Page

TEMPLATE Procedure: Creating Markup Language Tagsets

Concepts: Markup Languages and the TEMPLATE Procedure


Getting Familiar with Tagsets


Listing Tagset Names

SAS provides a set of tagsets. To get a list of the tagsets that SAS supplies and any tagsets that you have created and stored in the SASHELP.TMPLMST template store, submit the following SAS statements:

proc template;
   list tagsets;
run;  

By default, PROC TEMPLATE lists the tagsets in SASHELP.TMPLMST and SASUSER.TEMPLAT. Typically, you have read-only permissions to the SASHELP.TMPLMST item store where the SAS tagset directory is located. The SASUSER.TEMPLAT is the item store where the tagsets that you create or customize are stored by default.


Specifying Tagset Names

To specify a SAS tagset stored in SASHELP.TMPLMST or a tagset that you have created and stored in SASUSER.TEMPLAT or any other item store, use a two-level name: TAGSETS.tagset-name. For example, tagsets.chtml or tagsets.mytagset are valid two-level tagset names. By default, SAS knows that the specified tagset is stored in either SASHELP.TMPLMST or SASUSER.TEMPLAT.

To specify a tagset that you have created and stored in an item store other than SASUSER.TEMPLAT, assign the item store to the ODS search path with the ODS PATH statement. For information about the ODS PATH statement, see ODS PATH Statement.


Viewing the Contents of a Tagset

To view the contents of a tagset, use the SAS windowing environment or the TEMPLATE procedure.


Understanding Events

A tagset controls output generation through a series of events and variables. An event defines what is written to the output file. Here are some key points about events:

For example, here is a simple event for an HTML table output:

define event table;1 
start:2 
      put '<table>' nl;
finish:
      put '</table>' nl;
end;

In the event:

[1] The DEFINE EVENT statement begins the event and assigns it the name TABLE.

[2] The START section defines the beginning portion of the event, and the FINISH section defines the ending portion of the event. An event for a table needs START and FINISH sections because ODS needs to know how to define the beginning and the ending. ODS also expects other events to define how to format the table's rows and columns. The PUT statements specify to write the tags <table> and </table> to the output file, and to add a new line after each tag.

The following event does not include a start and finish section. The PUT statements specify to write the tags <TD> and </TD> to the output file. In addition, the event variable VALUE is used so that the data value from the SAS procedure or data set is written to the output file. The data value is enclosed with the <TD> and </TD> tags.

define event data;
      put '<TD>';
      put VALUE;
      put '</TD>';
end;


Understanding Variables

A variable is a programming structure that is used to hold data. A variable holds the data that is assigned to it until you assign a new value or end the program. Each variable has a unique name and holds information that is either internal information to handle the requested output (metadata that is used by ODS or the XML LIBNAME engine) or is information that is directly related to the output itself. For example, the variable COLCOUNT holds the value for the number of columns in the output, and the variable DATE holds the date.

Variables that are used by tagsets are divided into two groups: internally generated and user-created.

There are three logical divisions of internally generated variables:

event variable

a variable that includes text, formatting, and data values. These variables can originate in many places, such as the table template, the procedure, the title, or byline processing.

style variable

a variable that specifies a value for one aspect of the presentation. Style variables are specified by the ODS style attributes that are currently in use. The style variables are only differentiated from other event variables in that you know exactly where they originate. For more information on style attributes, see TEMPLATE Procedure: Creating a Style Template (Definition).

dynamic variable

a variable that is dynamically created within SAS. Because these variables are dynamically created, their names, or how they are used, is unknown. These variables are dynamic because they are not defined by ODS, but by applications such as SAS/GRAPH and the XML LIBNAME engine. Dynamic variables are designated by a preceding @ symbol. Dynamic variables are listed with the DYNAMIC statement. For more information about SAS/GRAPH, see SAS/GRAPH: Reference.

There are five types of user-created variables:

dictionary variable

an array that contains a list of numbers or text strings that are identified by a key. A dictionary variable has, as part of its name, a preceding '$' symbol and a subscript that contains a text string or a variable that has a character value. The text string or variable within the subscript is called a key. Keys are case preserving and case sensitive. After dictionary variables are created, they are globally available in all events and persist until you unset them with the UNSET statement.

For example, the following dictionary variable is identifying the entry in the $MyDictionary variable that contains the text 'dog': $MyDictionary['dog']. In this example, the key is 'dog'. Dictionary variables are accessed sequentially by using the ITERATE and NEXT statements.

list variable

an array that contains a list of numbers or text strings that are indexed. A list variable has, as part of its name, a preceding '$' symbol and a subscript that is empty or contains a number or numeric variable. The number within the subscript is called an index. After they are created, list variables are globally available in all events and persist until you unset them with the UNSET statement.

List entries are accessed by positive or negative indexes. Positive indexes start at the beginning of a list. Negative indexes start at the end of a list. For example, the list variable $Mylist[2] identifies the second entry in the list variable $Mylist. In this case, the index is 2. The list variable $Mylist[-2] identifies the second entry from the end of the list variable $Mylist. In this case, the index is [-2]. List variables are accessed sequentially by using the ITERATE and NEXT statements.

macro variable

a variable that is part of the SAS macro programming language. Macro variables must be specified with the MVAR or NMVAR statements. After they are declared, macro variables can be used anywhere within an event. See the MVAR Statement and NMVAR Statement for more information.

memory variables

areas of memory that contain numeric data, character data, or lists of numeric or character data. A memory variable is classified as a dictionary variable if it is created with a subscript that contains a key. A memory variable is classified as a list variable if it is created with a subscript that is empty or contains an index. If you omit a key or an index, then the memory variable is a numeric or character scalar variable, depending on the variable's value.

scalar variable

an area of memory that contains numeric or character data. Scalar variables must be preceded by the '$' symbol. After scalar variables are created, they are globally available in all events and persist until you unset them with the UNSET statement.

stream variable

a temporary item store that contains output. All output from PUT statements is directed to the open stream variable until it is closed. Stream variables must be preceded by the '$$' symbol except when used with the OPEN or PUTSTREAM statements. Stream variables are created with the SET, EVAL, or OPEN statements, within the DEFINE EVENT statement. Stream variables are different from other variables in that they can hold very large amounts of data. They can hold very large amounts of data because as they increase in size they are written to disk as needed.


Displaying Event Variables and Their Values

Because variables represent data, their values might or might not be present, depending on the SAS procedure and the job. For example, some variables have values only if they are specified with procedure options or style options. Other variables have values because the internal information, such as how many columns are in the output, is needed. For example, TAGSETS.CHTML contains the event COLSPECS, which uses the event variable COLCOUNT so that ODS knows how many columns are in the output:

define event colspecs;
      put '<p>' nl '<table';
      putq ' columns=' COLCOUNT;
      put ' cellpadding=2 border=1>' nl;
end;

To determine which variables have values and what the values are, use the EVENT_MAP statement to submit the SAS program. For more information, see Defining a Tagset Using the EVENT_MAP Tagset. For a list of event variables and their descriptions, see Event Variables.


Creating Custom Tagsets


Methods for Creating Custom Tagsets

To create a tagset, use the TEMPLATE procedure to define the tagset. In general, three methods are available to create a custom tagset:


Inheriting Events in a Tagset

Tagsets can inherit events from each other. For example, the SAS tagset TAGSETS.WMLOLIST inherits most of its events from TAGSETS.WML, and TAGSETS.IMODE gets most of its events from TAGSETS.CHTML. Inheriting events from an existing tagset is the easiest way to define a new tagset.

To inherit events, a tagset uses the PARENT= attribute in the DEFINE TAGSET statement to specify the name of a tagset from which to inherit. When a parent is specified for a tagset, all of the tagset options, attributes, and statements that are specified in the parent's template are used in the new template, unless the new template overrides them. That is, in the new tagset, an event can override the operation of the same-named event that is defined in the parent tagset. For example, if the parent tagset defines an event named TABLE, then you can change the operation in the new tagset by redefining the event named TABLE.

For an example of inheriting events in a tagset, see Creating a Tagset through Inheritance.


Defining a Tagset Using the EVENT_MAP Tagset

SAS procedures that generate ODS output use a standard set of events and variables. To generate customized output, create a customized tagset with customized events. However, in order to customize the events, you need to know the names of the events that ODS uses.

A good way to start defining the customized tagset is to use the EVENT_MAP tagset that SAS supplies. This enables you to determine which events are triggered and which variables are used by an event to send output from a SAS process to an output file. When you run a SAS process with TAGSETS.EVENT_MAP, ODS writes XML markup to an output file that shows all event names and variable names as tags. In the output, tag names are the event names. Tag attributes are the variables that have values for those events.

For example, the following statements run ODS MARKUP with TYPE=EVENT_MAP to see which events and variables ODS uses for various parts of the PROC PRINT output:

ods markup type=event_map file='custom-tagset-filename.xml';

   proc print data=sashelp.class;
      where Height gt 60;
   run;

   ods markup close;

Here is the listing output and resulting XML file:

Listing Output

The SAS System         1

                        Obs    Name       Sex    Age    Height    Weight

                          1    Alfred      M      14     69.0      112.5
                          3    Barbara     F      13     65.3       98.0
                          4    Carol       F      14     62.8      102.5
                          5    Henry       M      14     63.5      102.5
                          8    Janet       F      15     62.5      112.5
                          9    Jeffrey     M      13     62.5       84.0
                         12    Judy        F      14     64.3       90.0
                         14    Mary        F      15     66.5      112.0
                         15    Philip      M      16     72.0      150.0
                         16    Robert      M      12     64.8      128.0
                         17    Ronald      M      15     67.0      133.0
                         19    William     M      15     66.5      112.0

XML File

<?xml version='1.0' encoding='windows-1252'?>

<doc operator='user' sasversion='9.1' saslongversion='9.01.01B0D06102003' 
      date='2003-06-11' time='15:55:02' encoding='windows-1252' event_name='doc' 
      trigger_name='attr_out' class='Body' index='IDX' just='c'>
  <doc_head event_name='doc_head' trigger_name='attr_out' class='Body' 
      index='IDX' just='c'>
    <doc_meta event_name='doc_meta' trigger_name='attr_out' class='Body' 
      index='IDX' just='c'/>
    <auth_oper event_name='auth_oper' trigger_name='attr_out' class='Body' 
      index='IDX' just='c'/>
    <doc_title event_name='doc_title' trigger_name='attr_out' class='Body' 
      index='IDX' just='c'/>
    <stylesheet_link event_name='stylesheet_link' trigger_name='attr_out' 
      index='IDX' just='c'/>
    <javascript event_name='javascript' trigger_name='attr_out' class='Body' 
      index='IDX' just='c'>
      <startup_function event_name='startup_function' trigger_name='attr_out' 
         class='StartUpFunction' index='IDX' just='c'>
      </startup_function>
      <shutdown_function event_name='shutdown_function' trigger_name='attr_out' 
         class='ShutDownFunction' index='IDX' just='c'>
      </shutdown_function>
    </javascript>
  </doc_head>
  <doc_body event_name='doc_body' trigger_name='attr_out' class='Body'
      index='IDX' just='c'>
    <proc event_name='proc' trigger_name='attr_out' name='Print' 
      index='IDX' just='c'>
      <anchor event_name='anchor' trigger_name='attr_out' class='Body' name='IDX' 
         index='IDX' just='c'/>
      <page_setup event_name='page_setup' trigger_name='attr_out' class='Body' 
         index='IDX' just='c'>
        <system_title_setup_group event_name='system_title_setup_group' trigger_name='attr_out'
          class='Body' colcount='1' index='IDX' just='c'>
          <title_setup_container event_name='title_setup_container' trigger_name='attr_out' 
            class='SysTitleAndFooterContainer' colcount='1' index='IDX' just='c'>
            <title_setup_container_specs event_name='title_setup_container_specs' trigger_name='attr_out' 
               class='SysTitleAndFooterContainer' colcount='1' index='IDX' just='c'>
              <title_setup_container_spec event_name='title_setup_container_spec' trigger_name='attr_out' 
                  colcount='1' type='string' index='IDX' just='c' width='100%'/>
            </title_setup_container_specs>
            <title_setup_container_row event_name='title_setup_container_row' trigger_name='attr_out' 
               colcount='1' index='IDX' just='c'>
              <system_title_setup event_name='system_title_setup' trigger_name='attr_out' 
                  class='SystemTitle' value='The SAS System' colcount='1' index='IDX' just='c'>
              </system_title_setup>
            </title_setup_container_row>
          </title_setup_container>
        </system_title_setup_group>
      </page_setup>
      
...more xml tagged output...

               </table_body>
            </table>
          </output>
        </leaf>
      </proc_branch>
    </proc>
  </doc_body>
</doc>

In the XML output that is generated by EVENT_MAP, PROC PRINT uses events named DOC_HEAD, PROC, TABLE, and so on. The TABLE event uses data from event variables such as STATE, CLASS, and TYPE. After you know the events and variables that generate the output, define the tagset and customize your events. For example, you could redefine the TABLE event to produce customized output.

To define a tagset with which to customize your output, start by specifying TAGSETS.EVENT_MAP as the parent tagset. As you redefine events to customize output, these events replace the default events that are defined in the EVENT_MAP tagset. In addition, you can remove the operation of a default event by redefining it as an empty event in the tagset. When you are satisfied with the customized output, remove the EVENT_MAP inheritance and the empty events. Then the output will reflect only the events you defined.

Note:   When you first run a SAS process and specify TYPE=EVENT_MAP, you can also generate a stylesheet along with the body file. The stylesheet shows which style attributes you are using.  [cautionend]


Alternatives to EVENT_MAP

To create other types of output, you can use one of the following tagsets as alternatives:


Defining a Tagset Using SAS DATA Step Functions

A SAS DATA step function performs a computation or system manipulation on arguments and returns a value. In Base SAS software, you can use SAS functions in DATA step programming statements, WHERE expressions, macro language statements, the REPORT procedure, Structured Query Language (SQL), and in statements that are used when creating custom tagsets. Functions can be used on any statement within the tagset language. For information on DATA step functions and statements, see SAS Language Reference: Dictionary and SAS Language Reference: Concepts.

Previous Page | Next Page | Top of Page