Post Info

Comments 6 Comments »
Trackback Trackback this post
Tags Tags: , ,

Technorati Tags

php, simplexml, xml

RSS Comments

Add Children with SimpleXML

Thu, 11 May 2006 3:05 UTC

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:

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

    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.


6 Responses to “Add Children with SimpleXML”

fuckin A man! that’s awesome!

Comment by Robert K
Thu, 11 May 2006 at 5:29 UTC | Permalink

The registerXPathNamespace() function allows you to associate a prefix with an XML Namespace URI. A prefix is necessary to make XPath queries against elements that live under a namespace. (e.g. ”//xhtml:p” to find all “p” elements in the namespace bound to the “xhtml” prefix.)

Use this function when needing to access namespaced elements under a default namespace to create a prefix for that namespace. It’s also helpful when you cannot control the XML document you’re consuming and the provider may alter namespace prefixes without warning.

Comment by Adam Trachtenberg
Thu, 11 May 2006 at 14:19 UTC | Permalink

Thanks for the clarification on that, Adam. I think my problem was that I wasn’t using a proper XPath query, so the function wasn’t doing anything for me.

Comment by Ben Ramsey
Thu, 11 May 2006 at 14:23 UTC | Permalink

If only I had seen this a mere week ago!!! After some considerable work, I have managed to do this in the DOM – but it is such hard work. Many Many Thanks for this.

Comment by SteamSHIFT
Fri, 12 May 2006 at 10:04 UTC | Permalink

NB: It’s worth re-iterating this requires at least PHP version 5.1.3

Comment by SteamSHIFT
Fri, 12 May 2006 at 11:32 UTC | Permalink

Please, im a very new to php and xml:
if i have books.xml that contains:

how do i use this code to add a book? everything i tried errored.
Could you please email me an example? thank you very much in advance, i am very grateful!

Comment by Steve (noob)
Tue, 30 May 2006 at 14:04 UTC | Permalink