[Phpxd-commits] CVS: phpXD/include/parser DTDParser.php,1.2,1.3
Status: Beta
Brought to you by:
growbal
From: Thomas D. <th...@us...> - 2002-01-29 17:47:15
|
Update of /cvsroot/phpxd/phpXD/include/parser In directory usw-pr-cvs1:/tmp/cvs-serv11842/include/parser Modified Files: DTDParser.php Log Message: Index: DTDParser.php =================================================================== RCS file: /cvsroot/phpxd/phpXD/include/parser/DTDParser.php,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** DTDParser.php 2002/01/27 01:23:10 1.2 --- DTDParser.php 2002/01/29 17:47:12 1.3 *************** *** 19,55 **** var $DTDTokens; var $parameterEntities; var $elements; var $currentElement; ! function parse($str) { if (!empty($str)) { while (preg_match('=(.*)\%([a-z,A-Z,0-9,\.]*);(.*)$=sU', $str, $ent)) { $str = preg_replace('=<!--.*-->=sU', '', $str); ! while (preg_match('=(.*)<!ENTITY[ ,\n,\r,\t]*\%[ ,\n,\r,\t]*([a-z,A-Z,0-9,\.]*)[ ,\n,\r,\t]*PUBLIC[ ,\n,\r,\t]*"([a-z,A-Z,0-9,\-,/, ]*)"[ ,\n,\r,\t]*"([a-z,A-Z,0-9,\.,\-,_,/]*)"[ ,\n,\r,\t]*>(.*)$=sU', $str, $ent)) { if ($this->file_exists($this->currentDir."/".$ent[4])) { $this->parameterEntities[$ent[2]] = preg_replace('=<!--.*-->=sU', '', implode("", file($this->currentDir."/".$ent[4]))); } $str = $ent[1].$ent[5]; } ! while (preg_match('=(.*)<!ENTITY[ ,\n,\r,\t]*\%[ ,\n,\r,\t]*([a-z,A-Z,0-9,\.]*)[ ,\n,\r,\t]*"(.*)"[ ,\n,\r,\t]*>(.*)$=sU', $str, $ent)) { $this->parameterEntities[$ent[2]] = $ent[3]; $str = $ent[1].$ent[4]; } ! foreach ($this->parameterEntities as $ent => $body) { ! $str = str_replace("%".$ent.";", $body, $str); } } $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_set_object($parser, $this); ! // parse only the dtd xml_set_default_handler($parser, "handleDefault"); - // xml_set_unparsed_entity_decl_handler($parser, - // "handleUnparsedEntityDecl"); - - // xml_set_external_entity_ref_handler($parser, "handleExternalEntityRef"); if (!xml_parse($parser, $str, true)) { --- 19,85 ---- var $DTDTokens; var $parameterEntities; + var $parameterEntitiesDefined; var $elements; var $currentElement; + var $currentAttlist; ! function parse($str, $dtdonly = true) { if (!empty($str)) { + // Make dummy xml string to use expat as parser/scanner. + if ($dtdonly) { + $str = "<!DOCTYPE null [".$str."]><null />"; + } + + // search and replace parameter entities while (preg_match('=(.*)\%([a-z,A-Z,0-9,\.]*);(.*)$=sU', $str, $ent)) { $str = preg_replace('=<!--.*-->=sU', '', $str); ! while (preg_match('=(.*)<!ENTITY[ ,\n,\r,\t]*\%[ ,\n,\r,\t]*'. ! '([a-z,A-Z,0-9,\.]*)[ ,\n,\r,\t]*PUBLIC'. ! '[ ,\n,\r,\t]*"([a-z,A-Z,0-9,\-,/, ]*)"'. ! '[ ,\n,\r,\t]*"([a-z,A-Z,0-9,\.,\-,_,/]*)"'. ! '[ ,\n,\r,\t]*>(.*)$=sU', $str, $ent)) { if ($this->file_exists($this->currentDir."/".$ent[4])) { + if (isset($this->parameterEntitiesDefined[$ent[2]]) && + ($this->parameterEntitiesDefined[$ent[2]] == true)) { + // redefined parameter entity => replace current string + foreach ($this->parameterEntities as $entref => $body) { + $ent[1] = str_replace("%".$entref.";", $body, $ent[1]); + } + } $this->parameterEntities[$ent[2]] = preg_replace('=<!--.*-->=sU', '', implode("", file($this->currentDir."/".$ent[4]))); + $this->parameterEntitiesDefined[$ent[2]] = true; } $str = $ent[1].$ent[5]; } ! while (preg_match('=(.*)<!ENTITY[ ,\n,\r,\t]*\%[ ,\n,\r,\t]*'. ! '([a-z,A-Z,0-9,\.]*)[ ,\n,\r,\t]*"(.*)"'. ! '[ ,\n,\r,\t]*>(.*)$=sU', $str, $ent)) { ! if (isset($this->parameterEntitiesDefined[$ent[2]]) && ! ($this->parameterEntitiesDefined[$ent[2]] == true)) { ! // redefined parameter entity => replace current string ! foreach ($this->parameterEntities as $entref => $body) { ! $ent[1] = str_replace("%".$entref.";", $body, $ent[1]); ! } ! } $this->parameterEntities[$ent[2]] = $ent[3]; + $this->parameterEntitiesDefined[$ent[2]] = true; $str = $ent[1].$ent[4]; } ! foreach ($this->parameterEntities as $entref => $body) { ! $str = str_replace("%".$entref.";", $body, $str); } } + + // Use expat as parser/scanner for finding syntax errors in the dtd. + // So an array of tokens is provided, which is used as input for + // the parseToken method. $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_set_object($parser, $this); ! // Only interested in the dtd. xml_set_default_handler($parser, "handleDefault"); if (!xml_parse($parser, $str, true)) { *************** *** 67,71 **** } ! function parseFile($filename) { if ($this->file_exists($filename)) { $path = explode("/", $filename); --- 97,101 ---- } ! function parseFile($filename, $dtdonly = true) { if ($this->file_exists($filename)) { $path = explode("/", $filename); *************** *** 75,80 **** } $content = implode("", file($filename)); ! $content = "<!DOCTYPE null [".$content."]><null />"; ! return $this->parse($content); } else { --- 105,109 ---- } $content = implode("", file($filename)); ! return $this->parse($content, $dtdonly); } else { *************** *** 101,121 **** if ($token == "[") { $this->parseInternalDTD($tokens, $offset + 2); ! // foreach ($this->elements as $element) { ! // echo $element->tagName." -- "; ! // if ($element->children == null) { ! // echo "EMPTY"; ! // } ! // else { ! // echo $element->children->toString(); ! // } ! // echo "<br>"; ! // } ! exit; } if ($token == "SYSTEM") { $this->parseExternalSystemDTD($tokens, $offset + 2); } if ($token == "PUBLIC") { $this->parseExternalPublicDTD($tokens, $offset + 2); } } --- 130,142 ---- if ($token == "[") { $this->parseInternalDTD($tokens, $offset + 2); ! return; } if ($token == "SYSTEM") { $this->parseExternalSystemDTD($tokens, $offset + 2); + return; } if ($token == "PUBLIC") { $this->parseExternalPublicDTD($tokens, $offset + 2); + return; } } *************** *** 126,141 **** case "<!ELEMENT": { $this->parseElement($tokens, $offset + 1); ! $currentElement = $this->currentElement; ! $currentElement->children =& $this->currentElement->children; ! echo $this->currentElement->tagName." -- "; ! unset($this->currentElement); ! if ($currentElement->children != null) { echo $currentElement->children->toString()."<br>"; ! } ! $this->elements[] =& $currentElement; $offset = $this->skipToGt($tokens, $offset + 1); break; } case "<!ATTLIST": { $offset = $this->skipToGt($tokens, $offset + 1); break; --- 147,163 ---- case "<!ELEMENT": { $this->parseElement($tokens, $offset + 1); ! $currentElement = $this->currentElement; ! $currentElement->children =& $this->currentElement->children; ! echo $this->currentElement->tagName." -- "; ! unset($this->currentElement); ! if ($currentElement->children != null) { echo $currentElement->children->toString()."<br>"; ! } ! $this->elements[] =& $currentElement; $offset = $this->skipToGt($tokens, $offset + 1); break; } case "<!ATTLIST": { + $this->parseAttList($tokens, $offset + 1); $offset = $this->skipToGt($tokens, $offset + 1); break; *************** *** 165,169 **** $token = $this->removeQuotes($tokens[$offset]); $DTDParser = new DTDParser(); ! $DTDParser->parseFile($token); } --- 187,196 ---- $token = $this->removeQuotes($tokens[$offset]); $DTDParser = new DTDParser(); ! $DTDParser->parseFile($token, true); ! // merge definitions from $DTDParser with this ! $token = $tokens[$offset + 1]; ! if ($token == "[") { ! $this->parseInternalDTD($tokens, $offset + 2); ! } } *************** *** 175,182 **** $DTDParser = new DTDParser(); // $DTDParser->parseFile("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); ! $DTDParser->parseFile("../xhtml1-strict.dtd"); break; } } } --- 202,214 ---- $DTDParser = new DTDParser(); // $DTDParser->parseFile("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); ! $DTDParser->parseFile("../xhtml1-strict.dtd", true); break; } } + // merge definitions from $DTDParser with this + $token = $tokens[$offset + 2]; + if ($token == "[") { + $this->parseInternalDTD($tokens, $offset + 2); + } } *************** *** 300,303 **** --- 332,373 ---- } + function parseAttList($tokens, $offset) { + $name = $tokens[$offset]; + $this->currentAttlist = new DTDAttList($name); + $this->parseAttributes($tokens, $offset + 1); + } + + function parseAttributes($tokens, $offset) { + while ($tokens[$offset] != ">") { + $name = $tokens[$offset]; + echo $name; + $type = $tokens[$offset + 1]; + if ($type == "(") { + $attribute = new DTDAttribute($name, "ENUMERATION"); + // Enumeration + $offset += 2; + while ($tokens[$offset] != ")") { + if ($tokens[$offset] != "|") { + $attribute->value[] = $tokens[$offset]; + } + $offset++; + } + } + else { + $attribute = new DTDAttribute($name, $type); + $offset++; + } + $default = $tokens[$offset + 1]; + $attribute->default = $default; + if ($default == "#FIXED") { + $attribute->defaultValue = $this->removeQuotes($tokens[$offset + 2]); + $offset++; + } + $offset += 2; + } + } + + + function removeQuotes($str) { if (($str[0] == "\"") && ($str[strlen($str) - 1] == "\"")) { *************** *** 335,346 **** } - function handleExternalEntityRef($parser, $openEntityNames, $base, $systemId, $publicId) { - return true; - } - - function handleUnparsedEntityDecl($parser, $entityName, $base, $systemId, $publicId, $notationName) { - return true; - } - function file_exists($filename) { $file = @fopen($filename, "r"); --- 405,408 ---- *************** *** 390,400 **** } class DTDElementChild extends DTDNode { ! // Number of that child ! // 1 = one time ! // 2 = ? - zero or one time ! // 3 = * - zero or more times ! // 4 = + - one or more times ! var $number = 1; var $any = false; --- 452,479 ---- } + class DTDAttList extends DTDNode { + var $attributes; + var $element; + + function DTDAttList($element) { + $this->element = $element; + } + } + + class DTDAttribute extends DTDNode { + var $name; + var $type; + var $value; + var $default; + var $defaultValue; + + function DTDAttribute($name, $type) { + $this->name = $name; + $this->type = $type; + } + } + class DTDElementChild extends DTDNode { ! var $number = ""; var $any = false; *************** *** 418,436 **** } function setNumber($number) { ! switch ($number) { ! case "?": { ! $this->number = 2; ! break; ! } ! case "+": { ! $this->number = 3; ! break; ! } ! case "*": { ! $this->number = 4; ! break; ! } ! } } --- 497,503 ---- } + function setNumber($number) { ! $this->number = $number; } *************** *** 442,446 **** return "#PCDAZA"; } ! return $this->tagName." / ".$this->number; } } --- 509,513 ---- return "#PCDAZA"; } ! return $this->tagName.$this->number; } } *************** *** 468,472 **** $str .= $child->toString(); } ! $str .= ") / ".$this->number; return $str; } --- 535,539 ---- $str .= $child->toString(); } ! $str .= ")".$this->number; return $str; } *************** *** 498,502 **** $str .= $child->toString(); } ! $str .= ") / ".$this->number; return $str; } --- 565,569 ---- $str .= $child->toString(); } ! $str .= ")".$this->number; return $str; } |