The following
TEMPLATE procedure defines a customized tagset named Tagsets.Custom.
You can use the following
code as a template to define your own customized tagsets. For example,
to create your own customized tagset, only the EmitMeta, EmitRow,
and EmitCol events would require minor modifications.
proc template;
/* +------------------------------------------------+
| |
+------------------------------------------------+ */
define tagset tagsets.custom ;
notes "SAS XML Engine output event model(interface)";
indent = 3;
map = '<>&"''';
mapsub = '/</>/&/"/'/';
/* +------------------------------------------------+
| |
+------------------------------------------------+ */
define event XMLversion;
put '<?xml version="1.0"';
putq ' encoding=' ENCODING;
put ' ?>' CR;
break;
end;
define event XMLcomment;
put '<!-- ' CR;
put ' ' TEXT CR;
put ' -->' CR;
break;
end;
define event initialize;
set $LIBRARYNAME 'LIBRARY' ;
set $TABLENAME 'DATASET' ;
set $COLTAG 'column' ;
set $META 'FULL' ;
eval $is_engine 1;
eval $is_procprint 0;
eval $is_OUTBOARD 1;
end;
/* +------------------------------------------------+
| |
+------------------------------------------------+ */
define event doc;
start:
trigger initialize;
trigger XMLversion;
break;
finish:
break;
end;
define event doc_head;
start:
break;
finish:
break;
end;
define event doc_body;
start:
break;
finish:
break;
end;
define event proc;
start:
break / if frame_name ; /* set by ODS statement use */
eval $is_OUTBOARD 0 ; /* default for non-engine */
do / if cmp(XMLCONTROL, "OUTBOARD"); /* only the engine sets this */
eval $is_OUTBOARD 1 ;
else ;
eval $is_OUTBOARD 0 ;
done ;
break;
finish:
break;
end;
define event leaf;
start:
/*
* PROC PRINT
* data set reference is in the value and label fields
* and NOT in the output_label field
*/
eval $is_engine 0; /* NOT ENGINE */
break / if ^cmp("Print", name);
eval $is_procprint 1; /* PROC PRINT */
eval $regex prxparse("/\.(.+)/");
eval $match prxmatch($regex, value);
set $TABLENAME prxposn($regex, 1, value);
break;
finish:
break;
end;
define event output;
start:
break / if $is_procprint ;
eval $is_engine 0; /* NOT ENGINE */
set $TABLENAME name / if name; /* TABLE VIEWER */
break;
finish:
break;
end;
define event table;
start:
unset $col_names;
unset $col_types;
unset $col_width;
eval $index 1;
eval $index_max 0;
set $TABLENAME name / if name; /* LIBNAME ENGINE */
set $META XMLMETADATA / if XMLMETADATA ; /* LIBNAME ENGINE */
set $SCHEMA XMLSCHEMA / if XMLSCHEMA ; /* LIBNAME ENGINE */
break;
finish:
break;
end;
define event colspecs;
start:
break / if cmp(XMLMETADATA, "NONE");
finish:
break / if cmp(XMLMETADATA, "NONE");
end;
define event colgroup;
start:
break / if cmp(XMLMETADATA, "NONE");
finish:
break / if cmp(XMLMETADATA, "NONE");
end;
/* +------------------------------------------------+
| |
+------------------------------------------------+ */
define event colspec_entry;
start:
break / if ^$is_engine and $index eq 1 and cmp(name, "Obs");
eval $index_max $index_max+1;
set $col_names[] name;
set $col_types[] type;
set $col_width[] width;
break;
finish:
break;
end;
define event table_head;
start:
break;
finish:
break;
end;
define event table_body;
start:
trigger EmitMeta ;
break;
finish:
trigger EmitMeta ;
break;
end;
/* +------------------------------------------------+
| |
+------------------------------------------------+ */
define event row;
start:
break / if !cmp(SECTION, "body");
break / if cmp(XMLMETADATA, "ONLY");
eval $index 1;
unset $col_values;
break;
finish:
break / if !cmp(SECTION, "body");
break / if cmp(XMLMETADATA, "ONLY");
trigger EmitRow ;
break;
end;
define event data;
start:
break / if !cmp(SECTION, "body");
do / if $is_engine ;
break / if !cmp(XMLCONTROL, "Data");
else ;
break / if !cmp(HTMLCLASS, "Data");
done ;
break / if cmp(XMLMETADATA, "ONLY");
set $name $col_names[$index];
do / if exists(MISSING);
eval $is_MISSING 1;
eval $value_MISSING MISSING;
set $col_values[$name] " ";
else ;
eval $is_MISSING 0;
set $col_values[$name] VALUE;
done;
break;
finish:
break / if !cmp(SECTION, "body");
do / if $is_engine ;
break / if !cmp(XMLCONTROL, "Data");
else ;
break / if !cmp(HTMLCLASS, "Data");
done ;
break / if cmp(XMLMETADATA, "ONLY");
set $name $col_names[$index];
eval $index $index+1;
break;
end;
/* +------------------------------------------------+
| |
| at this point, we just take over XML output. |
| EmitRow() is triggered each time the data is |
| loaded into the $col_values array. |
| |
| we can output anything we desire from here... |
| |
+------------------------------------------------+ */
define event EmitMeta; 1
start:
put '<' $LIBRARYNAME '>' CR ;
put ' <!-- ' CR ;
put ' List of available columns' CR ;
eval $index 1;
iterate $col_names ;
do /while _value_;
put ' ' $index ' ' _value_ CR ;
next $col_names;
eval $index $index+1;
done;
put ' -->' CR ;
break;
finish:
put '</' $LIBRARYNAME '>' ;
break;
end;
define event EmitRow; 2
ndent;
put "<STUDENT>" CR ;
ndent;
set $name "Name"; trigger EmitCol ;
set $name "Height"; trigger EmitCol ;
set $name "Weight"; trigger EmitCol ;
xdent;
put "</STUDENT>" CR ;
xdent;
break;
end;
define event EmitCol; 3
unset $value;
set $value $col_values[$name];
put '<' $name '>' ;
put $value ;
put '</' $name '>' CR ;
break;
end;
end; /* custom */
run;
1 |
The
EmitMeta event generates an XML comment that contains a list of the
variables from the SAS data set. The event contains an example of
iteration for a list variable, which processes all of the variables
in the SAS data set. For more information about iteration, see the
ITERATE statement in the TEMPLATE procedure DEFINE EVENT statement
in SAS Output Delivery System: User's Guide.
|
2 |
The
EmitRow event creates XML output from the three SAS data set observations.
The EmitRow event names specific variables to process, which are Name,
Height, and Weight.
|
3 |
The
EmitCol event creates generic-looking XML for each processed variable.
|