User Contributed Notes 19 notes

What makes SimpleXMLElement tricky to work with is that it feels and behaves like an object, but is actually a system RESOURCE, (specifically a libxml resource).

That's why you can't store a SimpleXMLElement to $_SESSION or perform straight comparison operations on node values without first casting them to some type of object. $_SESSION expects to store 'an object' and comparison operators expect to compare 2 'objects' and SimpleXMLElements are not objects.

When you echo or print a node's value, PHP converts the value (a resource) into a string object for you. It's a time saver for sure, but can fool you into thinking that your SimpleXMLElement is an object.

SimpleXML supports Array/Iteration-Methods. Therefore it is possible to

add attributesedit attributesremove attributes

add nodesedit nodesremove nodes

This is the reason why SimpleXML provides only add-methods not deleting- or editing-methods. We also need this methods because SimpleXML acts as a normal class andnew member will not converted to a new node.

Deleting a node seems not to be possible within a foreach-loop. The reason is simple. To do that we need a valid key, but the Iterator only gives us a "understandable feedback" on which node we are working on: the tag name.

Warning to anyone trying to parse XML with a key name that includes a hyphen ie.)<subscribe> <callback-url>example url</callback-url></subscribe>

In order to access the callback-url you will need to do something like the following:<?php$xml = simplexml_load_string($input);$callback = $xml->{"callback-url"};?>If you attempt to do it without the curly braces and quotes you will find out that you are returned a 0 instead of what you want.

Figuring out how to access the properties of a SimpleXmlElement object was a little tricky for me. In particular, it took a while to discover that I needed to cast my SimpleXmlElement properties to be of type "string" to print them or do comparisons on them. For instance, assuming you already have a string of xml in $xmlstr...

<?php$sxml= new SimpleXmlElement($xmlstr);

if ((string) $sxml->property== "somevalue") { echo (string) $sxml->property;}?>The properties of a SimpleXmlElement object are objects themselves, so you need to put "(string)" before them, which casts their values to a string instead of an object. I assume if you were doing a numeric comparison you'd want to cast to an (int) or something numeric instead.

here goes my contribution for those whom are struggling to understand how SimpleXMLElement works.

After some time trying to figure out how this works, I've came up to this small example:

<?php $xmlstr = "<?xml version='1.0' ?>\n".// optionally you can specify a xml-stylesheet for presenting the results. just uncoment the following line and change the stylesheet name. /* "<?xml-stylesheet type='text/xsl' href='xml_style.xsl' ?>\n". */"<book></book>";

// create the SimpleXMLElement object with an empty <book> element$xml = new SimpleXMLElement($xmlstr);

// add some child nodes$xml->addChild("title", "Title of my book");$xml->addChild("abstract", "My book is about learning to work with SimpleXMLElement");

Here is a more namespace-aware version of the earlier function for attaching one SimpleXMLElement to another. I'm sure it could still be further improved (right now it generates some redundant xmlns definitions), but it seems to be working well enough for my purposes so far.

I'm using SimpleXML for, ofcourse, it's simplicity, however I did wanted to manipulate the xml and combining one SimpleXMLElement with any other, so I wrote this function to add a SimpleXMLElement-child.