Utility Routines

The following utility routines are defined in dtd.pl:

Note:
The routine DTDprint_tree should only be called after DTDread_dtd has been called.

Routine Descriptions

DTDis_attr_keyword

&'DTDis_attr_keyword($word);

DTDis_attr_keyword returns 1 if $word is an attribute content reserved value, otherwise, it returns 0. In the reference concrete syntax, the following values of $word will return 1:

Character case is ignored.

       

DTDis_elem_keyword

&'DTDis_elem_keyword($word);

DTDis_elem_keyword returns 1 if $word is an element content reserved value, otherwise, it returns 0. In the reference concrete syntax, the following values of $word will return 1:

Character case is ignored.

       

DTDis_group_connector

&'DTDis_group_connector($char);

DTDis_group_connector returns 1 if $char is an group connector, otherwise, it returns 0. The following values of $char will return 1:

       

DTDis_occur_indicator

&'DTDis_occur_indicator($char);

DTDis_occur_indicator returns 1 if $char is an occurence indicator, otherwise, it returns 0. The following values of $char will return 1:

       

DTDis_tag_name

&'DTDis_tag_name($string);

DTDis_tag_name returns 1 if $string is a legal tag name, otherwise, it returns 0. Legal characters in a tag name are defined by the $namechars variable. By default, a tag name may only contain the characters "A-Za-z_.-".

DTDprint_tree

&'DTDprint_tree($elem, $depth, FILEHANDLE);

DTDprint_tree prints the content hierarchy of a single element, $elem, to a maximum depth of $depth to the file specified by FILEHANDLE. If FILEHANDLE is not specified then output goes to STDOUT. A depth of 5 is used if $depth is not specified. The root of the tree has a depth of 1.

The routine cuts (prunes) at elements that exist at higher (or equal) levels or if $depth has been reached. The string "..." is appended to an element if it has been pruned due to pre-existance at a higher (or equal) level.

Pruning the tree at repeat elements is necessary to avoid a combinatorical explosion with recursive element definitions.

Here's an example of what the output will look like due to pruning of recursive element contents:

         htmlplus
         |
         |_body
         |  |
         |  |_address
         |  |  |
         |  |  |_p ...
         |  | 
         |  |_div1
         |  |  |
         |  |  |_address ...
         |  |  |_div2 ...
         |  |  |_div3 ...
         |  |  |_div4 ...
         |  |  |_div5 ...
         |  |  |_div6 ...


If you see an element with "...", just search through the output until you find the element without the "...".

       
Since the tree outputed is static, the inclusion and exclusion sets of elements are treated specially. Inclusion and exclusion elements inherited from ancestors are not propagated down to determine what elements are printed, but special markup is presented at a given element if there exists inclusion and exclusion elements from ancestors. The reason inclusion and exclusion elements are not propagated down is because of the pruning done. An element w/o "..." may be the only place of reference to see the content hierarchy of that element. However, the element may occur in multiple contents and have different ancestoral inclusion and exclusion elements applied to it.

Have I lost you? Maybe an example may help:

         openbook
         |
         |_d1
         |  | (I): idx needbegin needend newline
         |  |
         |  |_abbrev
         |  |  | (Ia): idx needbegin needend newline
         |  |  | (X): needbegin needend
         |  |  |
         |  |  |_#PCDATA
         |  |  |_acro
         |  |  |  | (Ia): idx needbegin needend newline
         |  |  |  | (Xa): needbegin needend
         |  |  |  |
         |  |  |  |_#PCDATA
         |  |  |  |_sub ...
         |  |  |  |_super ...
         |  |  | 

Ignoring the lines starting with ()'s, one gets the content hierachy of an element as defined by the DTD without concern of where it may occur in the overall structure. The ()'s line give additional information regarding the element with respect to its existance within a specific context. For example, when an acro element occurs within openbook/d1/abbrev, along with its normal content, it can contain idx and newline elements due to inclusions from ancestors. However, it cannot contain needbegin, needend regardless of its defined content since an ancestor(s) excludes them.

Note:
Exclusions override inclusions. If an element occurs in an inclusion set and an exclusion set, the exclusion takes precedence. Therefore, in the above example, needbegin, needend are excluded from acro.
Explanation of ()'s keys:

(I)
The list of inclusion elements defined by the current element. Since this is part of the content model of the element, the inclusion elements are printed as part of the content hierarchy of the current element.
(Ia)
The list of inclusion elements due to ancestors. This is listed as reference to determine the content of an element within a given context. None of the ancestoral inclusion elements are printed as part of the content hierarchy of the element.
(X)
The list of exclusion elements defined by the current element. Since this is part of the content model of the element, the exclusion elements prevent elements defined in the base content and inclusion sets to be printed.
(Xa)
The list of exclusion elements due to ancestors. This is listed as reference to determine the content of an element within a given context. None of the ancestoral exclusion elements have any effect on the printing of the content hierarchy of the current element.
       

DTDreset

&'DTDreset();

DTDreset clears all data associated with the DTD read via DTDread_dtd. This routine is useful if multiple DTDs need to be processed.

       

Back to dtd.pl.


Earl Hood, ehood@convex.com
dtd.pl 2.1.0