Thread: [Phpxd-commits] CVS: phpXD phpXD.php,1.23,1.24 sample.php,1.6,1.7
Status: Beta
Brought to you by:
growbal
From: Thomas D. <th...@us...> - 2002-01-25 22:18:20
|
Update of /cvsroot/phpxd/phpXD In directory usw-pr-cvs1:/tmp/cvs-serv12964 Modified Files: phpXD.php sample.php Log Message: Index: phpXD.php =================================================================== RCS file: /cvsroot/phpxd/phpXD/phpXD.php,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -r1.23 -r1.24 *** phpXD.php 2001/12/01 23:51:12 1.23 --- phpXD.php 2002/01/25 22:18:18 1.24 *************** *** 7,540 **** // $Id$ ! require("include/node.php"); ! require("include/attr.php"); ! require("include/characterdata.php"); ! require("include/comment.php"); ! require("include/document.php"); ! require("include/documentfragment.php"); ! require("include/documenttype.php"); ! require("include/domexception.php"); ! require("include/domimplementation.php"); ! require("include/element.php"); ! require("include/entity.php"); ! require("include/entityreference.php"); ! require("include/namednodemap.php"); ! require("include/nodelist.php"); ! require("include/processinginstruction.php"); ! require("include/text.php"); ! require("include/cdatasection.php"); ! /** ! * This class offers methods for accessing the nodes of a XML document using ! * the Document Object Model Level 1 (DOM). For parsing the XML files, the PHP ! * XML extension (libexpat) is used. Some interface supports DOM Level 2 yet. ! * ! * @package phpXD ! * @author Thomas Dohmke <th...@do...> ! * @version $Revision$ ! */ ! class phpXD { ! /** ! * The Document node. ! * ! * @private ! * @type Document ! */ ! var $document; ! ! /** ! * The current Element node which is parsed. Only valid while ! * parsing a XML file! ! * ! * @private ! * @type Node ! */ ! var $currentNode; ! ! /** ! * The last node which is parsed. Only valid while parsing a XML file! ! * ! * @private ! * @type Node ! */ ! var $lastNode; ! ! /** ! * A CDataSection is parsed. All strings will be collected to one ! * CDataSection node. Only valid while parsing a XML file! ! * ! * @private ! * @type boolean ! */ ! var $parseCData = false; ! ! /** ! * The parsed DTD string. Only valid while parsing a XML file! ! * ! * @private ! * @type string ! */ ! var $parsedDTD = false; ! ! /** ! * The parsed DTD is an internal DTD. Only valid while parsing ! * a XML file! ! * ! * @private ! * @type boolean ! */ ! var $parsedDTDInternal = false; ! ! /** ! * A array with the defined namespaces. ! * ! * @private ! * @type array ! */ ! var $namespaces = false; ! ! /** ! * The Constructor of the class. If $file is set, the XML file ! * is loaded. ! * ! * @public ! * @param $file <code>string</code> ! * @returns phpXD ! */ ! function phpXD($file = "") { ! $this->namespaces["xml"] = "http://www.w3.org/XML/1998/namespace"; ! $this->namespaces["xmlns"] = "http://www.w3.org/2000/xmlns/"; ! ! if (!empty($file)) { ! $this->loadFile($file); ! } ! } ! ! /** ! * Loads the XML file specified by $file and creates the DOM tree. ! * ! * @public ! * @param $file <code>string</code> ! * @returns phpXD ! */ ! function loadFile($file) { ! if (file_exists($file)) { // && is_readable($file)) { ! $content = implode("", file($file)); ! ! if (!empty($content)) { ! $this->document = new Document(); ! ! $parser = xml_parser_create(); ! ! xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); ! ! xml_set_object($parser, $this); ! ! xml_set_element_handler($parser, "handleStartElement", ! "handleEndElement"); ! xml_set_character_data_handler($parser, "handleCharacterData"); ! xml_set_processing_instruction_handler($parser, ! "handleProcessingInstruction"); ! xml_set_default_handler($parser, "handleDefault"); ! ! if (!xml_parse($parser, $content, true)) { ! $this->displayError("XML error in file %s, line %d: %s", ! $file, xml_get_current_line_number($parser), ! xml_error_string(xml_get_error_code($parser))); ! } ! ! xml_parser_free($parser); ! } ! } ! else { ! $this->displayError("File %s could not be found or read.", $file); ! } ! } ! ! /** ! * Saves the DOM tree recursively to the XML file specified by $file. ! * If $trim is set to true, all whitespaces from beginning and end of a ! * the XML markup are stripped. ! * ! * @public ! * @param $dom <a href="Document.html">Document</a> ! * @param $trim <code>boolean</code> ! * @returns void ! */ ! function saveFile($file, $trim = false) { ! $fp = fopen($file, "w"); ! fwrite($fp, "<?xml version=\"1.0\"?>\n"); ! $this->saveTree($this->document, 0, $trim, $text); ! fwrite($fp, $text); ! fclose($fp); ! } ! ! /** ! * Writes the DOM tree recursively to the string $text as XML. ! * ! * @private ! * @param $dom <a href="Document.html">Document</a> ! * @param $deep <code>boolean</code> ! * @param $trim <code>boolean</code> ! * @param $text <code>string</code> ! * @returns void ! */ ! function saveTree(&$dom, $deep, $trim, &$text) { ! $space = ""; ! if (!$trim) { ! for ($i = 0; $i < $deep; $i++) $space .= "\t"; ! } ! if ($dom->nodeType == CDATA_SECTION_NODE) { ! $text .= $space; ! $text .= "<![CDATA["; ! $output = $dom->getData(); ! $text .= $output; ! $text .= "]]>\n"; ! } ! if ($dom->nodeType == COMMENT_NODE) { ! $text .= $space; ! $text .= "<!--"; ! $output = $dom->getData(); ! if (!(strpos($output, "\n") === false)) { ! $break = "\n"; ! } ! else { ! $break = ""; ! $space = ""; ! } ! $text .= $break.$space; ! $output = str_replace("\n", "\n".$space, $output); ! $text .= $output; ! $text .= $break.$space; ! $text .= "-->\n"; ! } ! if ($dom->nodeType == DOCUMENT_NODE) { ! if (!empty($dom->doctype)) { ! if (!empty($dom->doctype->publicId) && ! !empty($dom->doctype->systemId)) { ! $text .= "<!DOCTYPE ".$dom->doctype->name." PUBLIC ". ! $dom->doctype->systemId." ".$dom->doctype->publicId.">\n"; ! } ! else { ! if (!empty($dom->doctype->systemId)) { ! $text .= "<!DOCTYPE ".$dom->doctype->name." SYSTEM ". ! $dom->doctype->systemId.">\n"; ! } ! else { ! $text .= $dom->doctype->internalSubset."\n"; ! } ! } ! } ! if ($dom->hasChildNodes()) { ! $this->saveTree($dom->firstChild, $deep, $trim, $text); ! } ! $this->saveTree($dom->documentElement, $deep, $trim, $text); ! } ! if ($dom->nodeType == DOCUMENT_FRAGMENT_NODE) { ! $this->saveTree($dom->firstChild, $trim, $text); ! } ! if ($dom->nodeType == ELEMENT_NODE) { ! $text .= $space; ! $text .= "<".$dom->tagName; ! if (isset($dom->attributes)) { ! for ($i = 0; $i < $dom->attributes->getLength(); $i++) { ! $elem =& $dom->attributes->item($i); ! $text .= " ".$elem->getName()."=\"".$elem->getValue()."\""; ! } ! } ! ! if ($dom->hasChildNodes()) { ! $text .= ">\n"; ! $this->saveTree($dom->firstChild, $deep+1, $trim, $text); ! $text .= $space; ! $text .= "</".$dom->tagName.">\n"; ! } ! else { ! $text .= " />\n"; ! } ! } ! if ($dom->nodeType == PROCESSING_INSTRUCTION_NODE) { ! $text .= $space; ! $output = $dom->getData(); ! $text .= "<?".$dom->getTarget()." "; ! $text .= $output; ! $text .= " ?>\n"; // <? ! } ! if ($dom->nodeType == TEXT_NODE) { ! $text .= $space; ! $text .= $dom->getData(); ! $text .= "\n"; ! } ! if (isset($dom->nextSibling)) { ! $this->saveTree($dom->nextSibling, $deep, $trim, $text); ! } ! } ! ! /** ! * The Element Start Handler for Expat. ! * ! * @private ! * @returns void ! */ ! function handleStartElement($parser, $name, $attributes) { ! if (!(strpos($name, ":") === false)) { ! $prefix = substr($name, 0, strpos($name, ":")); ! if (is_array($attributes) && ! !empty($attributes["xmlns:".$prefix])) { ! $namespace = $attributes["xmlns:".$prefix]; ! } ! else { ! if (is_array($this->namespaces) && ! !empty($this->namespaces[$prefix])) { ! $namespace = $this->namespaces[$prefix]; ! } ! else { ! $this->displayError("XML error: unknown namespace in line %d.", ! xml_get_current_line_number($parser)); ! } ! } ! ! $this->namespaces[$prefix] = $namespace; ! } ! ! if (!(strpos($name, ":") === false)) { ! $newChild =& $this->document->createElementNS($namespace, $name); ! ! if ($newChild == NAME_SPACE_ERR) { ! $this->displayError("XML error: namespace not valid in line %d.", ! xml_get_current_line_number($parser)); ! } ! } ! else { ! $newChild =& $this->document->createElement($name); ! } ! ! if (!isset($this->document->documentElement)) { ! $this->document->documentElement =& $newChild; ! $this->currentNode =& $this->document->documentElement; ! } ! else { ! $this->currentNode->appendChild($newChild); ! $this->currentNode =& $newChild; ! } ! ! if (is_array($attributes)) { ! while (list($name, $value) = each($attributes)) { ! if (!(strpos($name, ":") === false)) { ! $prefix = substr($name, 0, strpos($name, ":")); ! $localName = substr($name, strpos($this->nodeName, ":")+1); ! if ($prefix == "xmlns") { ! $this->namespaces[$localName] = $value; ! $namespace = $this->namespaces["xmlns"]; ! } ! else { ! if (is_array($attributes) && ! !empty($attributes["xmlns:".$prefix])) { ! $namespace = $attributes["xmlns:".$prefix]; ! } ! else { ! if (is_array($this->namespaces) && ! !empty($this->namespaces[$prefix])) { ! $namespace = $this->namespaces[$prefix]; ! } ! else { ! $this->displayError("XML error: unknown namespace". ! " in line %d.", ! xml_get_current_line_number($parser)); ! } ! } ! } ! ! $result = $this->currentNode->setAttributeNS($namespace, $name, ! $value); ! ! if ($result == NAME_SPACE_ERR) { ! $this->displayError("XML error: namespace not valid in line %d.", ! xml_get_current_line_number($parser)); ! } ! ! $attr =& $this->currentNode->getAttributeNode($name); ! $attr->specified = true; ! } ! else { ! $this->currentNode->setAttribute($name, $value); ! $attr =& $this->currentNode->getAttributeNode($name); ! $attr->specified = true; ! } ! } ! } ! ! $this->lastNode =& $this->currentNode; ! } ! ! /** ! * The Element End Handler for Expat. ! * ! * @private ! * @returns void ! */ ! function handleEndElement($parser, $name) { ! $this->currentNode =& $this->currentNode->parentNode; ! $this->lastNode =& $this->currentNode; ! } ! ! /** ! * The CharacterData Handler for Expat. ! * ! * @private ! * @returns void ! */ ! function handleCharacterData($parser, $text) { ! if ($this->parseCData) { ! if ($this->lastNode->nodeType == CDATA_SECTION_NODE) { ! $this->lastNode->appendData($text); ! } ! else { ! $this->lastNode =& $this->currentNode->appendChild( ! $this->document->createCDataSection($text)); ! } ! } ! else { ! $text = str_replace("\t", " ", $text); ! $text = str_replace("\n", " ", $text); ! $text = str_replace("\r", " ", $text); ! $text = str_replace(" ", " ", $text); ! $text = preg_replace("/\ +/", " ", $text); ! ! $this->lastNode =& $this->currentNode->appendChild( ! $this->document->createTextNode($text)); ! } ! } ! ! /** ! * The ProcessingInstruction Handler for Expat. ! * ! * @private ! * @returns void ! */ ! function handleProcessingInstruction($parser, $target, $data) { ! if (!isset($this->document->documentElement)) { ! $this->document->appendChild( ! $this->document->createProcessingInstruction($target, $data)); ! } ! else { ! $this->lastNode =& $this->currentNode->appendChild( ! $this->document->createProcessingInstruction( ! $target, $data)); ! } ! } ! ! /** ! * The DTD Handler. Expat has no DTD Handler callback, so this ! * is set by handleDefault. ! * ! * @private ! * @returns void ! */ ! function handleDTD($parser, $data) { ! $data = trim($data); ! ! if (!empty($data)) { ! $this->parsedDTD .= " ".$data; ! } ! if ($data == "[") { ! $this->parseDTDInternal = true; ! } ! if ($data == "]") { ! $this->parseDTDInternal = false; ! } ! if ((substr($this->parsedDTD, strlen($this->parsedDTD)-1) == ">") && ! !$this->parseDTDInternal) { ! $this->document->doctype = new DocumentType(); ! ! // this is just a hack to differ between internal and external DTDs ! $DTD = explode(" ", $this->parsedDTD); ! ! $this->document->doctype->name = $DTD[1]; ! if ($DTD[2] == "SYSTEM") { ! $this->document->doctype->systemId = $DTD[3]; ! } ! else { ! if ($DTD[2] == "PUBLIC") { ! $this->document->doctype->publicId = $DTD[3]; ! $this->document->doctype->systemId = $DTD[4]; ! } ! else { ! $this->document->doctype->internalSubset = $this->parsedDTD; ! } ! } ! ! xml_set_default_handler($parser, "handleDefault"); ! return true; ! } ! } ! ! /** ! * The Default Handler for Expat. ! * ! * @private ! * @returns void ! */ ! function handleDefault($parser, $data) { ! $data = trim($data); ! ! if (!(strpos($data, "<!--") === false)) { ! $data = str_replace("<!--", "", $data); ! $data = str_replace("-->", "", $data); ! if (!isset($this->document->documentElement)) { ! $this->document->appendChild( ! $this->document->createComment($data)); ! } ! else { ! $this->lastNode =& $this->currentNode->appendChild( ! $this->document->createComment($data)); ! } ! return true; ! } ! ! if ($data == "<![CDATA[") { ! $this->parseCData = true; ! return true; ! } ! ! if ($data == "]]>" && $this->parseCData) { ! $this->parseCData = false; ! return true; ! } ! ! if ($data == "<!DOCTYPE") { ! $this->parsedDTD .= $data; ! xml_set_default_handler($parser, "handleDTD"); ! return true; ! } ! ! return false; ! } ! ! /** ! * Displays errors, which occur while parsing. ! * ! * @private ! * @returns void ! */ ! function displayError($message) { ! if (func_num_args() > 1) { ! $arguments = func_get_args(); ! ! $command = "\$message = sprintf(\$message, "; ! ! for ( $i = 1; $i < sizeof($arguments); $i++ ) { ! $command .= "\$arguments[".$i."], "; ! } ! ! $command = eregi_replace(", $", ");", $command); ! ! eval($command); ! } ! ! echo "<strong>phpXD error:</strong> ".$message; ! exit; ! } ! ! } ! ?> --- 7,29 ---- // $Id$ ! $path = ""; ! require($path."include/dom/Node.php"); ! require($path."include/dom/Attr.php"); ! require($path."include/dom/CharacterData.php"); ! require($path."include/dom/Comment.php"); ! require($path."include/dom/Document.php"); ! require($path."include/dom/DocumentFragment.php"); ! require($path."include/dom/DocumentType.php"); ! require($path."include/dom/DOMException.php"); ! require($path."include/dom/DOMImplementation.php"); ! require($path."include/dom/Element.php"); ! require($path."include/dom/Entity.php"); ! require($path."include/dom/EntityReference.php"); ! require($path."include/dom/NamedNodeMap.php"); ! require($path."include/dom/NodeList.php"); ! require($path."include/dom/ProcessingInstruction.php"); ! require($path."include/dom/Text.php"); ! require($path."include/dom/CDataSection.php"); ! require($path."include/parser/DOMParser.php"); ! ?> \ No newline at end of file Index: sample.php =================================================================== RCS file: /cvsroot/phpxd/phpXD/sample.php,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** sample.php 2002/01/25 21:44:40 1.6 --- sample.php 2002/01/25 22:18:18 1.7 *************** *** 152,156 **** } ! $dom = new phpXD("sample.xml"); ! echoTree($dom->document); ?> --- 152,156 ---- } ! $parser = new DOMParser(); ! echoTree($parser->parseFile("sample.xml")); ?> |