views:

127

answers:

1

a.php

#!/usr/bin/php
<?php
class HtmlTable extends DOMElement
{   
        public function __construct($height, $width)
        {   
                parent::__construct("table");
                for ($i = 0; $i < $height; ++$i) {
                        $row = $this->appendChild(new DOMElement("tr"));
                        for($j = 0; $j < $width; ++$j) {
                                $row->appendChild(new DOMElement("td"));
                        }   
                }   
        }   
}   

$document = new DOMDocument("1.0", "UTF-8");
$document->registerNodeClass("DOMElement", "HtmlTable");
$document->appendChild(new HtmlTable(3, 2));
$document->saveXML();

Running it gets

Fatal error: Uncaught exception 'DOMException' with message 'No Modification Allowed Error' in /home/www/a.php:9
Stack trace:
#0 /home/www/a.php(9): DOMNode->appendChild(Object(DOMElement))
#1 /home/www/a.php(19): HtmlTable->__construct(3, 2)
#2 {main}
  thrown in /home/www/a.php on line 9
A: 

copy and pasting from a php.net comment

After searching how to extend the DOMDocument and DOMElement I found a way in the bug: http://bugs.php.net/bug.php?id=35104. The following code shows how:

<?php
class extDOMDocument extends DOMDocument {
 public function createElement($name, $value=null) {
  $orphan = new extDOMElement($name, $value); // new  sub-class object
  $docFragment = $this->createDocumentFragment(); // lightweight container maintains "ownerDocument"
  $docFragment->appendChild($orphan); // attach
  $ret = $docFragment->removeChild($orphan); // remove
  return $ret; // ownerDocument set; won't be destroyed on  method exit
 }
 // .. more class definition
}

class extDOMElement extends DOMElement {
 function __construct($name, $value='', $namespaceURI=null) {
  parent::__construct($name, $value, $namespaceURI);
 }
  //  ... more class definition here
}

$doc = new extDOMDocument('test');
$el = $doc->createElement('tagname');
$el->setAttribute("attr", "val");
$doc->appendChild($el);

// append discards the DOMDocumentFragment and just adds its child nodes, but ownerDocument is maintained.
echo get_class($el)."<br/>";
echo get_class($doc->documentElement)."<br/>";
echo "<xmp>".$doc->saveXML()."</xmp>";
?>
Galen
Your extDOMElement constructor does not do the thing I want so this answer is useless
Michael Tsang
Nice attitude Michael. That will get you the answers you need. In stead of the attitude try to explain WHY it doesn't suit your needs.
fireeyedboy
seriously, not cool. you know you can change the constructor right? good luck
Galen