Unmarked Lists Nested Lists

print make_definition_list terms, defs; I n Perl, creat e t he t erm s and definit ions by invoking dt and dd , save t hem in an array, and pass t he array t o dl : my query = SELECT note, mnemonic FROM doremi ORDER BY id; my sth = dbh-prepare query; sth-execute ; my items = ; while my note, mnemonic = sth-fetchrow_array { handle possibility of NULL undef values note = defined note ? escapeHTML note : ; mnemonic = defined mnemonic ? escapeHTML mnemonic : ; push items, dt note; push items, dd mnemonic; } print dl items; Here is a slight ly m ore com plex exam ple. Each t erm is a dat abase nam e, and t he corresponding definit ion indicat es how m any t ables are in t he dat abase. The num bers are obt ained by issuing a SHOW TABLES query for each dat abase and count ing t he num ber of rows in t he result : get list of database names my db_ref = dbh-selectcol_arrayref SHOW DATABASES; my items = ; foreach my db_name {db_ref} { get list of table names in database; disable RaiseError for this query, to prevent script termination in case the current user has no access to the database dbh-{RaiseError} = 0; my tbl_ref = dbh-selectcol_arrayref SHOW TABLES FROM db_name; dbh-{RaiseError} = 1; my tbl_count = defined tbl_ref error? ? {tbl_ref} . tables no, get table count : cannot access; yes, indicate problem push items, dt escapeHTML db_name; push items, dd escapeHTML tbl_count; } print dl items; Not e t hat it s necessary t o t ake care not t o die on an error when issuing SHOW TABLES st at em ent s, should t he user running t he script not have access t o a given dat abase.

17.3.7 Unmarked Lists

A t ype of list not norm ally discussed as such is a list wit h no m arkings at all. This is sim ply a set of it em s, each on a separat e line. An unm arked list is very easy t o produce: fet ch each it em and add a break t ag aft er it . Heres an exam ple in JSP: c:forEach var=row items={rs.rows} c:out value={row.item} br c:forEach I f you already have t he it em s in an array, j ust it erat e t hrough it . For exam ple, in Perl, if you have a set of it em s in an array nam ed items , generat e t he list like t his: foreach my item items { handle possibility of NULL undef values item = defined item ? escapeHTML item : ; print item . br ; }

17.3.8 Nested Lists

Som e applicat ions display inform at ion t hat is m ost easily underst ood when present ed as a list of list s. The following exam ple displays st at e nam es as a definit ion list , grouped by t he init ial let t er of t he nam es. For each it em in t he list , t he t erm is t he init ial let t er, and t he definit ion is an unordered list of t he st at e nam es beginning wit h t hat let t er: A · Alabama · Alaska · Arizona · Arkansas C · California · Colorado · Connecticut D · Delaware ... One w ay t o produce such a list in Perl is as follows: get list of initial letters my ltr_ref = dbh-selectcol_arrayref SELECT DISTINCT UPPERLEFTname,1 AS letter FROM states ORDER BY letter; my items = ; get list of states for each letter foreach my ltr {ltr_ref} { my item_ref = dbh-selectcol_arrayref SELECT name FROM states WHERE LEFTname,1 = ? ORDER BY name, undef, ltr; item_ref = [ map { escapeHTML _ } {item_ref} ]; convert list of states to unordered list my item_list = ul li item_ref; for each definition list item, the initial letter is the term, and the list of states is the definition push items, dt ltr; push items, dd item_list; } print dl items; The preceding exam ple uses one query t o get t he list of dist inct let t ers, t hen anot her query for each let t er t o find t he st at es associat ed wit h each let t er. You could also ret rieve all t he inform at ion using a single query, t hen m arch t hrough t he result set and begin a new list it em each t im e you reach a new let t er: my sth = dbh-prepare SELECT name FROM states ORDER BY name; sth-execute ; my items = ; my names = ; my cur_ltr = ; while my name = sth-fetchrow_array { my ltr = uc substr name, 0, 1; initial letter of name if cur_ltr ne ltr beginning a new letter? { if names any stored-up names from previous letter? { for each definition list item, the initial letter is the term, and the list of states is the definition push items, dt cur_ltr; push items, dd ul li \names; } names = ; cur_ltr = ltr; } push names, escapeHTML name; } if names any remaining names from final letter? { push items, dt cur_ltr; push items, dd ul li \names; } print dl items; A t hir d approach uses a single query but separat es t he dat a-collect ion and HTML-generat ion phases: collect state names and associate each with the proper initial-letter list my sth = dbh-prepare SELECT name FROM states ORDER BY name; sth-execute ; my ltr = ; while my name = sth-fetchrow_array { my ltr = uc substr name, 0, 1; initial letter of name initialize letter list to empty array if this is first state for it, then add state to array ltr{ltr} = [ ] unless exists ltr{ltr}; push {ltr{ltr}}, name; } now generate the output lists my items = ; foreach my ltr sort keys ltr { encode list of state names for this letter, generate unordered list my ul_str = ul li [ map { escapeHTML _ } {ltr{ltr}} ]; push items, dt ltr, dd ul_str; } print dl items;

17.4 Displaying Query Results as Tables