dtddoc step 4: PHP code - exploring XML | WebReference

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