* Example usage:
* * $doc = new XHTMLDoc('<html><head><title>test</title> </head><body id="test"></body></html>');
* $doc->setValue('test', 'Document body');
* echo $doc->getDoc();
*
*
* The result will be:
* * <html>
* <head>
* <title>test</title>
* </head>
* <body id="test">
* Document body
* </body>
* </html>
*
* * @author Tommy Gildseth ; * @author Akili AS ; * @copyright Akili AS, June 2003 * @access public * @package XHTML */ class XHTMLDoc { //{{{ Class members /** * A reference to the root XmlNode of the XML tree representing the XHTML document * @access private */ var $_xmlTree; /** * This is the declaration which appears at the top of the XHTML document * @access private */ var $_docType; /** * Elements in the document, which have an id attribute. * @access private */ var $_elements; /** * The XML parser. * @access private */ var $_parser; //}}} End class member declarations //{{{Constructor /** * XHTMLDoc constructor * * @param string $document Either a string containing the XHTML document, or the * filename which contains it. * @access public */ function XHTMLDoc( $document ) { $this->_parser = new XmlParser(); if (strlen($document) < 100 && is_file($document)) $this->_parser->parseFile($document); else $this->_parser->parseString($document); $this->_xmlTree = $this->_parser->getRootNode(); if (is_object($this->_xmlTree)) { $this->_findIDElements($this->_xmlTree); $this->_docType = $this->_parser->doctype; $this->_parser->reset(); } }//}}}end Constructor //{{{_findIDElements /** * Find all elements which have an id attribute * * @param object XmlNode &$node reference to a XMLNode * @access private */ function _findIDElements( &$node ) { if (!$this->_checkAssert('_findIDElements', 'is_object($param)', 'INTERNAL ERROR:
parameter $node is not an XmlNode', $node)) { return false; } $children = &$node->getChildren(NUMERIC); $id = $node->getAttribute('id'); if ($id !== null) { $this->_elements[$id] = &$node; } $j = count($children); for ($i = 0; $i < $j; ++$i) { $this->_findIDElements( $children[$i] ); } }//}}}end function _findFormElements //{{{setValue /** * Set the value of the element identified by $id * * @param string $id the value of the id attribute of a XHTML element * (note: lowercase, ie. not ID) * @param string $value The value to assign to the element. * @access public */ function setValue( $id, $value ) { if (!$this->_checkID('setValue', $id)) return; $this->_elements[$id]->setValue($value); }//}}}end function setValue //{{{appendValue /** * Adds the value to the end of the element identified by $id's content * * @param string $id the value of the id attribute of a XHTML element (note: lowercase, ie. not ID) * @param string $value The value to assign to the element. * @access public */ function appendValue( $id, $value ) { if (!$this->_checkID('appendValue', $id)) return; $this->_elements[$id]->appendValue($value); }//}}}end function appendValue //{{{addAttribute /** * Add a attribute to the element identified by id * * @param string $id the value of the id attribute of a XHTML element * (note: lowercase, ie. not ID) * @param string $name Name of the attribute to add to the element * @param string $value The value to assign to the attribute. * @access public */ function addAttribute( $id, $name, $value ) { if (!$this->_checkID('addAttribute', $id)) return; $this->_elements[$id]->addAttribute($name, $value); }//}}}end function addAttribute //{{{addAttributes /** * Similar to XHTMLDoc::addAttribute() except this one lets you add multiple attributes at once * * @param string $id the value of the id attribute of a XHTML element * (note: lowercase, ie. not ID) * @param string $attributes an associative array of attribute name => * attribute value pairs * @access public */ function addAttributes( $id, $attributes ) { if (!$this->_checkID('addAttributes', $id)) return; foreach($attributes as $attrName => $attrValue) { $this->_elements[$id]->addAttribute($attrName, $attrValue); } }//}}}end function addAttributes //{{{addNode /** * Add a XmlNode to the children of the node identified by $id * * @param string $id the value of the id attribute of a XHTML element * (note: lowercase, ie. not ID) * @param object XmlNode $node The node to add * @access public */ function addNode( $id, $node ) { if (!$this->_checkID('addNode', $id)) return; $this->_elements[$id]->addChild('.', $node); $this->_findIDElements($node); }//}}}end function addNode //{{{remIDAttrib /** * Remove the ID attribute from all nodes * * @access public */ function remIDAttrib( ) { foreach ($this->_elements as $key=>$value) { $this->_elements[$key]->remAttribute('id'); } }//}}}end function remIDAttrib //{{{insertXHTMLDoc /** * Add a XHTML docuemnt to the xmltree, as a child of the node identified by $id * * @param string $id the value of the id attribute of a XHTML element * (note: lowercase, ie. not ID) * @param string $doc Either a string containing the document, or a filename of a * file containing the document. * @access public */ function insertXHTML( $id, $doc) { if (!$this->_checkID('addNode', $id)) return; if (strlen($doc) < 100 && is_file($doc)) $this->_parser->parseFile($doc); else $this->_parser->parseString($doc); $root = $this->_parser->getRootNode(); $this->addNode($id, $root); $this->_findIDElements($this->_xmlTree); $this->_parser->reset(); }//}}}end function insertXHTMLDoc //{{{getRootNode /** * Get the root node of the XHTML document * * @return object XmlNode The root node of the XML tree representing the XHTML document * @access public */ function getRootNode( ) { return $this->_xmlTree; }//}}}end function getRootNode //{{{getDoc /** * Get the XHTML document as a string * * @return string string representation of this XHTML document * @access public */ function getDoc( ) { if (!$this->_checkAssert('getDoc', '!is_null($this->_xmlTree)', 'XHTML document is empty')) { return; } return $this->_docType."\n".$this->_xmlTree->getXmlString(); }//}}}end function getDoc //{{{_checkID /** * @access private */ function _checkID($funcName, $id) { if (!assert ('isset($this->_elements[$id])')) { $dbt = debug_backtrace(); $errorMsg = 'Assertion failed in call to XHTMLDoc::'.$funcName.':
'; $errorMsg .= 'There is no document element with the id '.$id.'
'; $errorMsg .= 'This method was called from '.$dbt[1]['file'].':'.$dbt[1]['line']; $errorMsg .= '

Available elements are:

';
            echo $errorMsg;
            if (is_array($this->_elements))
                print_r(array_keys($this->_elements));
            echo '
'; $this->_printStackTrace( $dbt ); return 0; } return 1; }//}}}end function _checkID //{{{_checkAssert /** * @access private */ function _checkAssert($funcName, $assert, $msg, $param = null) { if (!assert ($assert)) { $dbt = debug_backtrace(); $errorMsg = 'Assertion failed in call to XHTMLDoc::'.$funcName.':
'; $errorMsg .= 'This method was called from '.$dbt[1]['file'].':'.$dbt[1]['line']; $errorMsg .= '
'.$msg.'

'; echo $errorMsg; $this->_printStackTrace( $dbt ); return 0; } return 1; }//}}}end function _checkAssert //{{{_printStackTrace /** * Prints a stacktrace of the callstack * * @access private */ function _printStackTrace( $dbt ) { if ($dbt === null) $dbt = debug_backtrace(); echo 'Complete trace of callstack:
'; array_shift($dbt); foreach($dbt as $eachCall) { echo $eachCall['function'].' called from '.$eachCall['file'].':'; echo $eachCall['line'].'
'; } echo '

'; }//}}}end function _printStackTrace } if (!function_exists('debug_backtrace')) { function debug_backtrace( ) { $arr = array('function' => __FUNCTION__, 'line' => __LINE__, 'file' => __FILE__, 'class' => __CLASS__, 'type' => 'Undefined', 'args' => 'Undefined'); return array($arr, $arr); } } ?>