dtddoc step 4: PHP code - exploring XML
dtddoc step 4: Generating HTML
The PHP solution
#!/usr/bin/php -q <?php include_once("DTD_parser.php"); function is_comment($item) { return get_class($item) == "dtdcomment"; } function get_dtddoc_comment($comment) { preg_match('/<(\w*)(\s+(\w+)="[^"]*")?>\s*(.*)(\n[\w\W]*)?/m', $comment->text, $match); return $match; } function is_not_empty($array) { return count($array) > 1; } function find_parents($dtd) { $parents = array(); foreach ($dtd->elements as $elt) { $sw = new StringWriter(); $elt->content->write($sw); $results = preg_split("/[(|)]/", $sw->toString()); $results = array_slice($results, 1, count($results)-2); foreach ($results as $result) { $child = trim($result); $parents[$child][] = $elt->name; } } return $parents; } function write_overview_page($fh, $dtd, $comments) { write_header($fh); fwrite($fh, "<h1>DTD Overview</h1>"); fwrite($fh, "<p>{$comments[' '][0]}</p>"); fwrite($fh, "<p>{$comments[' '][1]}</p>"); $root = $dtd->rootElement->name; fwrite($fh, "<h2>Root element</h2><p><a href=elt-$root.html>$root</a></p>"); write_footer($fh); } function write_tree_page($fh, $dtd, $comments) { write_header($fh); fwrite($fh, "<h1>Element Tree</h1>"); fwrite($fh, "<ul>"); write_tree_element($fh, $dtd, $comments, $dtd->rootElement->name); fwrite($fh, "</ul>"); write_footer($fh); } function write_tree_element($fh, $dtd, $comments, $eltName) { fwrite($fh, "<li><a href=elt-$eltName.html>$eltName</a>"); fwrite($fh, " - " . $comments[$eltName . ' '][0]); $content = $dtd->elements[$eltName]->content; if (is_subclass_of($content, 'dtdcontainer')) { $first = true; foreach ($content->items as $item) { if (get_class($item) == 'dtdname') { if ($first) { fwrite($fh, "<ul>"); $first = false; } write_tree_element($fh, $dtd, $comments,$item->value); } } if (!$first) fwrite($fh, "</ul>"); } } function write_index_page($fh, $dtd, $comments) { write_header($fh); fwrite($fh, "<h1>Index</h1>"); $index = array(); foreach ($dtd->elements as $elt) { insert_into_index($index, $elt->name, 'Element', $comments[$elt->name . ' '][0]); foreach ($elt->attributes as $att) { insert_into_index($index, "$att->name ($elt->name)", 'Attribute', $comments[$elt->name . ' ' . $att->name][0]); } } foreach ($dtd->entities as $ent) { insert_into_index($index, $ent->name, 'Entity', $ent->value); } foreach ($dtd->notations as $not) { insert_into_index($index, $not->name, 'Notation', $not->externalID->system); } fwrite($fh, "<table border=1><tr><th>Name</th><th>Type</th><th>Value</th></tr>"); natcasesort($index); foreach($index as $line) { fwrite($fh, "<tr><td>$line</td></tr>"); } fwrite($fh, "</table>"); write_footer($fh); } function insert_into_index(&$index, $name, $type, $value) { $sort = "<!--$name-->"; $sort .= ($type == 'Element') ? "<a href=elt-$name.html>$name</a>" : $name; array_push($index, "$sort</td><td>$type</td><td>$value"); } function write_notations_page($fh, $dtd, $comments) { write_header($fh); fwrite($fh, "<h1>Notations</h1>"); if (sizeof($dtd->notations) == 0) { fwrite($fh, "<p><em>None</em></p>"); } else { foreach ($dtd->notations as $not) { fwrite($fh, "<li>$not->name = $not->externalID->system</li>"); } } write_footer($fh); } function write_entities_page($fh, $dtd, $comments) { write_header($fh); fwrite($fh, "<h1>Entities</h1>"); if (sizeof($dtd->entities) == 0) { fwrite($fh, "<p><em>None</em></p>"); } else { fwrite($fh, "<ul>"); foreach ($dtd->entities as $ent) { fwrite($fh, "<li>$ent->name = $ent->value</li>"); } fwrite($fh, "</ul>"); } write_footer($fh); } class StringWriter { var $buffer = ''; function wprint($data) { $this->buffer .= $data; } function toString() { return $this->buffer; } } function write_element_page($fh, $dtd, $comments, $parents, $elt) { write_header($fh); fwrite($fh, "<h1>Element <$elt->name></h1>"); fwrite($fh, "<p>" . $comments[$elt->name . ' '][0] . "</p>"); $comment = $comments[$elt->name . ' '][1]; if ($comment) fwrite($fh, "<p>$comment</p>"); fwrite($fh, "<h2>Attributes</h2>"); if (sizeof($elt->attributes) == 0) { fwrite($fh, "<p><em>None</em></p>"); } else { fwrite($fh, "<dl>"); foreach ($elt->attributes as $att) { fwrite($fh, "<dt>$att->name {$att->decl->name} $att->defaultValue</dt>"); fwrite($fh, "<dd>" . $comments[$elt->name . ' ' . $att->name][0] . "</dd>"); } fwrite($fh, "</dl>"); } fwrite($fh, "<h2>Content</h2>"); $sw = new StringWriter(); $elt->content->write($sw); fwrite($fh, "<p>" . htmlify_content($sw->toString()) . "</p>"); fwrite($fh, "<h2>Parents</h2>"); $pars = $parents[$elt->name]; if (!$pars) { fwrite($fh, "<p><em>None</em></p>"); } else { fwrite($fh, "<p>"); foreach($pars as $parent) { fwrite($fh, "<a href=elt-$parent.html>$parent</a> "); } fwrite($fh, "</p>"); } write_footer($fh); } function htmlify_content($content) { return preg_replace("/([ (])(\w+)/", "$1<a href=elt-$2.html>$2</a>", $content); } function htmlify_comment($comment) { return preg_replace("/html:/", "", preg_replace("/<(\w+)>/", "<a href=elt-$1.html>$1</a>", $comment)); } function write_header($fh) { fwrite($fh, "<html><body><p>"); fwrite($fh, "<a href=dtd-overview.html>Overview</a> "); fwrite($fh, "<a href=dtd-tree.html>Tree</a> "); fwrite($fh, "<a href=dtd-index.html>Index</a> "); fwrite($fh, "<a href=dtd-notations.html>Notations</a> "); fwrite($fh, "<a href=dtd-entities.html>Entities</a> "); fwrite($fh, "</p>"); } function write_footer($fh) { fwrite($fh, "</body></html>"); fclose($fh); } $reader = new URLReader($argv[1]); $parser = new DTDparser($reader, false); $dtd = $parser->parse(true); $dtdcomments = array_filter(array_map("get_dtddoc_comment", array_filter($dtd->items, "is_comment")), "is_not_empty"); foreach ($dtdcomments as $comment) { $comments[$comment[1]." ".$comment[3]] = array(htmlify_comment($comment[4]), htmlify_comment($comment[5])); } $parents = find_parents($dtd); write_overview_page(fopen("dtd-overview.html", "w"), $dtd, $comments); write_tree_page(fopen("dtd-tree.html", "w"), $dtd, $comments); write_index_page(fopen("dtd-index.html", "w"), $dtd, $comments); write_notations_page(fopen("dtd-notations.html", "w"), $dtd, $comments); write_entities_page(fopen("dtd-entities.html", "w"), $dtd, $comments); foreach ($dtd->elements as $elt) { write_element_page(fopen("elt-$elt->name.html", "w"), $dtd, $comments, $parents, $elt); } ?>
Produced by Michael Claßen
URL: https://www.webreference.com/xml/column68/dtddoc.php.html
Created: Nov 11, 2002
Revised: Nov 11, 2002