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: http://www.webreference.com/xml/column68/dtddoc.php.html
Created: Nov 11, 2002
Revised: Nov 11, 2002


