Add Children with SimpleXML

I was very excited today while glancing through the code in ext/simplexml/simplexml.c to find some, as of yet, undocumented methods in PHP’s SimpleXMLElement class. This discovery came after I’ve spent several hours over the last couple of nights banging my head against the desk to figure out a way to create a class that extends SimpleXMLElement and adds a new method for adding a child, which would have to use DOM in order to work – or so I thought.

During this process, I’ve discovered two major limitations of SimpleXML:

  • You cannot override the SimpleXMLElement constructor; it is a final method in the internals
  • You can extend SimpleXMLElement and add new methods, but looping through child nodes creates new SimpleXMLElement objects that do not use your class and, thus, cannot use your methods

Nevertheless, I can get over these limitations after discovering these new SimpleXMLElement methods in PHP 5.1.4. In particular, the last three are what interest me most (these are not yet documented in the PHP manual ):

bool SimpleXMLElement->registerXPathNamespace(string prefix, string uri)
array SimpleXMLElement->getNamespaces([bool recursive])
array SimpleXMLElement->getDocNamespaces([bool recursive])
string SimpleXMLElement->getName()
object SimpleXMLElement->addChild(string name [, string value [, string ns]])
void SimpleXMLElement->addAttribute(string name, string value [,string ns])

Previously, one of the biggest limitations of SimpleXML was that you could not add new child nodes to an XML document. Adding attributes to an element was no problem, but in order to add a child element, you had to go a round-about way through importing the SimpleXML object to DOM with dom_import_simplexml(), adding the child element, and importing the DOM object back to SimpleXML with simplexml_import_dom(). This was messy and anything but simple.

Now, it’s clean and simple, as SimpleXML should be:

$xml = <<<XML
<book title="Fahrenheit 451" author="Ray Bradbury"/>
<book title="Stranger in a Strange Land" author="Robert Heinlein"/>
$sxe = new SimpleXMLElement($xml);
$new_book = $sxe->addChild('book');
$new_book->addAttribute('title', '1984');
$new_book->addAttribute('author', 'George Orwell');
echo $sxe->as<abbr title="">XML</abbr>;

UPDATE: I’ve added all of these (except for registerXPathNamespace(), which I can’t seem to figure out) to the documentation for SimpleXML in the PHP Manual. The documentation for each new method will be available the next time the scripts run to update the manual.