There seems to be a lot of talk about SimpleXML having a "problem" with CDATA, and writing functions to rip it out, etc. I thought so too, at first, but it's actually behaving just fine under PHP 5.2.6

"To compare an element or attribute with a string or pass it into a function that requires a string, you must cast it to a string using (string). Otherwise, PHP treats the element as an object."

If a tag contains CDATA, SimpleXML remembers that fact, by representing it separately from the string content of the element. So some functions, including print_r(), might not show what you expect. But if you explicitly cast to a string, you get the whole content.

Here is my simple SimpleXML wrapper function.As far as I can tell, it does the same as Julio Cesar Oliveira's (above).It parses an XML string into a multi-dimensional associative array.The second argument is a callback that is run on all data (so for example, if you want all data trimmed, like Julio does in his function, just pass 'trim' as the second arg).<?phpfunction unserialize_xml($input, $callback = null, $recurse = false)/* bool/array unserialize_xml ( string $input [ , callback $callback ] ) * Unserializes an XML string, returning a multi-dimensional associative array, optionally runs a callback on all non-array data * Returns false on all failure * Notes: * Root XML tags are stripped * Due to its recursive nature, unserialize_xml() will also support SimpleXMLElement objects and arrays as input * Uses simplexml_load_string() for XML parsing, see SimpleXML documentation for more info */{// Get input, loading an xml string with simplexml if its the top level of recursion$data = ((!$recurse) && is_string($input))? simplexml_load_string($input): $input;// Convert SimpleXMLElements to arrayif ($data instanceof SimpleXMLElement) $data = (array) $data;// Recurse into arraysif (is_array($data)) foreach ($data as &$item) $item = unserialize_xml($item, $callback, true);// Run callback and returnreturn (!is_array($data) && is_callable($callback))? call_user_func($callback, $data): $data;}?>

A looked through a lot of the sample code for reading XML files with CDATA, but they didn't work out that well for me. However, I found that the following piece of code worked perfectly for reading through a file using lots of CDATA.

Be careful checking for parse errors. An empty SimpleXMLElement may resolve to FALSE, and if your XML contains no text or only contains namespaced elements your error check may be wrong. Always use `=== FALSE` when checking for parse errors.

Theres a problem with the below workaround when serializing fields containing html CDATA. For any other content type then HTML try to modfiy function parseCDATA.Just add these lines before serializing.This is also a workaround for this bug http://bugs.php.net/bug.php?id=42001

If you want to serialize and unserialize SimpleXMLElement objects for caching, you need to transform the SimpleXMLElement object into a standard class object before unserializing.This is only if you want to cache converted data, the functionallity of the SimpleXMLElement will not be held.

It's worth noting that in the example above, $xml->body will actually return an object of type SimpleXMLElement, not a string, e.g.

SimpleXMLElement Object ( [0] => this is the text in the body tag )

If you want to get a string out of it you must explicitly cast it using (string) or double quotes, or pass $xml->body (or whatever attribute you want to access) to any function that returns a string, such as urldecode() or trim().

simplexml provides a neat way to do 'ini' files. Preferences for any number of users can be held in a single XML file having elements for each user name with user specific preferences as attributes of child elements. The separate <pref/>'s could of course be combined as multiple attributes of a single <pref/> element but this could get unwieldy.

In the sample code below the makeXML() function uses the simplexml_load_string function to generate some XML to play with and the readPrefs() function parses the requested users preferences into an array.

Simplexml's simplicity can be deceptive. Simplexml elements behave either as objects or strings, depending on the context in which they're used (through overloading of the __toString() method, I assume). Statements implying conversion to string treat them as strings, while assignment operations treat them as objects. This can lead to unexpected behavior if, for example, you are trying to compare the values of two Simplexml elements. The expected syntax will not work. To force conversion to strings, just "typecast' whatever Simplexml element you're using. For example: