XML 操作
在线手册:中文 英文
PHP手册

SimpleXML


XML 操作
在线手册:中文 英文
PHP手册
PHP手册 - N: SimpleXML

用户评论:

andrew at andrewluecke dot com (01-Apr-2012 08:00)

In many situations, the methods of supporting CDATA in comments above may inappropriate (especially if an external library is using simplexml).

Instead, you may simply cast CDATA elements to a string, such as:
print (string)$xml->cdataelement or (string)$xml->{'cdataelement'}

In my case, it eliminated the need for me to edit an external library file every time an upgrade for the file was released.

thedoc8786 at gmail dot com (24-Mar-2012 03:42)

FAIL! This function works better than the one I posted below:

<?php
   
function toArray($xml) {
       
$array = json_decode(json_encode($xml), TRUE);
       
        foreach (
array_slice($array, 0) as $key => $value ) {
            if ( empty(
$value) ) $array[$key] = NULL;
            elseif (
is_array($value) ) $array[$key] = toArray($value);
        }

        return
$array;
    }

thedoc8786 at gmail dot com (24-Mar-2012 12:19)

I know it is over-done, but the following is a super-short example of a XML to Array conversion function (recursive):

<?php
   
function toArray(SimpleXMLElement $xml) {
       
$array = (array)$xml;

        foreach (
array_slice($array, 0) as $key => $value ) {
            if (
$value instanceof SimpleXMLElement ) {
               
$array[$key] = empty($value) ? NULL : toArray($value);
            }
        }
        return
$array;
    }

salvocucinella at gmail dot com (30-Sep-2011 09:59)

Here is a snippet to convert a simple object to XML.
A class that does the job and an example how to use it

<?php
class Obj2xml {

    var
$xmlResult;
   
    function
__construct($rootNode){
       
$this->xmlResult = new SimpleXMLElement("<$rootNode></$rootNode>");
    }
   
    private function
iteratechildren($object,$xml){
        foreach (
$object as $name=>$value) {
            if (
is_string($value) || is_numeric($value)) {
               
$xml->$name=$value;
            } else {
               
$xml->$name=null;
               
$this->iteratechildren($value,$xml->$name);
            }
        }
    }
   
    function
toXml($object) {
       
$this->iteratechildren($object,$this->xmlResult);
        return
$this->xmlResult->asXML();
    }
}

   
//----test object----
   
$ob->field1=10;
   
$ob->field2->field21="textA";
   
$ob->field2->field22="textB";
   
//----test object----
   
   
$converter=new Obj2xml("root");
   
   
header("Content-Type:text/xml");

    echo
$converter->toXml($ob);
   
?>

xananax at yelostudio dot com (08-Sep-2011 02:25)

None of the XML2Array functions that I found satisfied me completely; Their results did not always fit the project I was working on, and I found none that would account for repeating XML elements (such as
<fields><field/><field/><field/></fields>)
So I rolled out my own; hope it helps someone.
<?php
/**
 * Converts a simpleXML element into an array. Preserves attributes.<br/>
 * You can choose to get your elements either flattened, or stored in a custom
 * index that you define.<br/>
 * For example, for a given element
 * <code>
 * <field name="someName" type="someType"/>
 * </code>
 * <br>
 * if you choose to flatten attributes, you would get:
 * <code>
 * $array['field']['name'] = 'someName';
 * $array['field']['type'] = 'someType';
 * </code>
 * If you choose not to flatten, you get:
 * <code>
 * $array['field']['@attributes']['name'] = 'someName';
 * </code>
 * <br>__________________________________________________________<br>
 * Repeating fields are stored in indexed arrays. so for a markup such as:
 * <code>
 * <parent>
 *     <child>a</child>
 *     <child>b</child>
 *     <child>c</child>
 * ...
 * </code>
 * you array would be:
 * <code>
 * $array['parent']['child'][0] = 'a';
 * $array['parent']['child'][1] = 'b';
 * ...And so on.
 * </code>
 * @param simpleXMLElement    $xml            the XML to convert
 * @param boolean|string    $attributesKey    if you pass TRUE, all values will be
 *                                            stored under an '@attributes' index.
 *                                            Note that you can also pass a string
 *                                            to change the default index.<br/>
 *                                            defaults to null.
 * @param boolean|string    $childrenKey    if you pass TRUE, all values will be
 *                                            stored under an '@children' index.
 *                                            Note that you can also pass a string
 *                                            to change the default index.<br/>
 *                                            defaults to null.
 * @param boolean|string    $valueKey        if you pass TRUE, all values will be
 *                                            stored under an '@values' index. Note
 *                                            that you can also pass a string to
 *                                            change the default index.<br/>
 *                                            defaults to null.
 * @return array the resulting array.
 */
function simpleXMLToArray(SimpleXMLElement $xml,$attributesKey=null,$childrenKey=null,$valueKey=null){

    if(
$childrenKey && !is_string($childrenKey)){$childrenKey = '@children';}
    if(
$attributesKey && !is_string($attributesKey)){$attributesKey = '@attributes';}
    if(
$valueKey && !is_string($valueKey)){$valueKey = '@values';}

   
$return = array();
   
$name = $xml->getName();
   
$_value = trim((string)$xml);
    if(!
strlen($_value)){$_value = null;};

    if(
$_value!==null){
        if(
$valueKey){$return[$valueKey] = $_value;}
        else{
$return = $_value;}
    }

   
$children = array();
   
$first = true;
    foreach(
$xml->children() as $elementName => $child){
       
$value = simpleXMLToArray($child,$attributesKey, $childrenKey,$valueKey);
        if(isset(
$children[$elementName])){
            if(
is_array($children[$elementName])){
                if(
$first){
                   
$temp = $children[$elementName];
                    unset(
$children[$elementName]);
                   
$children[$elementName][] = $temp;
                   
$first=false;
                }
               
$children[$elementName][] = $value;
            }else{
               
$children[$elementName] = array($children[$elementName],$value);
            }
        }
        else{
           
$children[$elementName] = $value;
        }
    }
    if(
$children){
        if(
$childrenKey){$return[$childrenKey] = $children;}
        else{
$return = array_merge($return,$children);}
    }

   
$attributes = array();
    foreach(
$xml->attributes() as $name=>$value){
       
$attributes[$name] = trim($value);
    }
    if(
$attributes){
        if(
$attributesKey){$return[$attributesKey] = $attributes;}
        else{
$return = array_merge($return, $attributes);}
    }

    return
$return;
}
?>

soloman at textgrid dot com (10-Aug-2011 01:06)

Three line xml2array:

<?php

$xml
= simplexml_load_string($xmlstring);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

?>

Ta da!

james at esilogix dot com (21-Jul-2011 03:55)

Here is a function I wrote that converts an associative array into an xml output.  It also includes tabs to ensure the xml output is easy to read.

<?php
 
/*
  * James Earlywine - July 20th 2011
  *
  * Translates a jagged associative array
  * to XML
  *
  * @param : $theArray - The jagged Associative Array
  * @param : $tabCount - for persisting tab count across recursive function calls
  */
function assocToXML ($theArray, $tabCount=2) {
   
//echo "The Array: ";
    //var_dump($theArray);
    // variables for making the XML output easier to read
    // with human eyes, with tabs delineating nested relationships, etc.
   
   
$tabCount++;
   
$tabSpace = "";
   
$extraTabSpace = "";
     for (
$i = 0; $i<$tabCount; $i++) {
       
$tabSpace .= "\t";
     }
    
     for (
$i = 0; $i<$tabCount+1; $i++) {
       
$extraTabSpace .= "\t";
     }
    
    
   
// parse the array for data and output xml
   
foreach($theArray as $tag => $val) {
        if (!
is_array($val)) {
           
$theXML .= PHP_EOL.$tabSpace.'<'.$tag.'>'.htmlentities($val).'</'.$tag.'>';
        } else {
           
$tabCount++;
           
$theXML .= PHP_EOL.$extraTabSpace.'<'.$tag.'>'.assocToXML($val, $tabCount);
           
$theXML .= PHP_EOL.$extraTabSpace.'</'.$tag.'>';
        }
    }
   
return
$theXML;
}
?>

streaver91 at gmail dot com (05-May-2011 04:49)

The BIGGEST differece between an XML and a PHP array is that in an XML file, the name of elements can be the same even if they are siblings, eg. "<pa><ch /><ch /><ch /></pa>", while in an PHP array, the key of which must be different.

I think the array structure developed by svdmeer can fit for XML, and fits well.

here is an example array converted from an xml file:
array(
"@tag"=>"name",
"@attr"=>array(
    "id"=>"1","class"=>"2")
"@text"=>"some text",
)

or if it has childrens, that can be:

array(
"@tag"=>"name",
"@attr"=>array(
    "id"=>"1","class"=>"2")
"@items"=>array(
    0=>array(
        "@tag"=>"name","@text"=>"some text"
    )
)

Also, I wrote a function that can change that array back to XML.

<?php
function array2XML($arr,$root) {
$xml = new SimpleXMLElement("<?xml version=\"1.0\" encoding=\"utf-8\" ?><{$root}></{$root}>");
$f = create_function('$f,$c,$a','
        foreach($a as $v) {
            if(isset($v["@text"])) {
                $ch = $c->addChild($v["@tag"],$v["@text"]);
            } else {
                $ch = $c->addChild($v["@tag"]);
                if(isset($v["@items"])) {
                    $f($f,$ch,$v["@items"]);
                }
            }
            if(isset($v["@attr"])) {
                foreach($v["@attr"] as $attr => $val) {
                    $ch->addAttribute($attr,$val);
                }
            }
        }'
);
$f($f,$xml,$arr);
return
$xml->asXML();
}
?>

info at kevinbelanger dot com (20-Jan-2011 05:07)

An easer way to get the text node if you can't access to [0] property of the simpleXMLElement is to use the sprintf function.

As gwhitescarver at yahoo dot com said, in some version of php 5 it is hard to access to text node of an element, but when you print the element, the [0] property is automaticaly returned.

Like if you echo() the element, the text node is return.

The sprintf function do the same:

<?php
$a
= array();

foreach (
$xml->children() as $child) {
 
$a[$child->getName()] = sprintf("%s", $child);
}
?>

phil at dier dot us (19-Jan-2011 07:37)

Here's a function I came up with to convert an associative array to XML.  Works for multidimensional arrays as well.

<?php
function assocArrayToXML($root_element_name,$ar)
{
   
$xml = new SimpleXMLElement("<?xml version=\"1.0\"?><{$root_element_name}></{$root_element_name}>");
   
$f = create_function('$f,$c,$a','
            foreach($a as $k=>$v) {
                if(is_array($v)) {
                    $ch=$c->addChild($k);
                    $f($f,$ch,$v);
                } else {
                    $c->addChild($k,$v);
                }
            }'
);
   
$f($f,$xml,$ar);
    return
$xml->asXML();
}
?>

philipp at strazny dot com (24-Nov-2010 01:33)

Here's a quick way to dump the nodeValues from SimpleXML into an array using the path to each nodeValue as key. The paths are compatible with e.g. DOMXPath. I use this when I need to update values externally (i.e. in code that doesn't know about the underlying xml). Then I use DOMXPath to find the node containing the original value and update it.

<?php
function XMLToArrayFlat($xml, &$return, $path='', $root=false)
{
   
$children = array();
    if (
$xml instanceof SimpleXMLElement) {
       
$children = $xml->children();
        if (
$root){ // we're at root
           
$path .= '/'.$xml->getName();
        }
    }
    if (
count($children) == 0 ){
       
$return[$path] = (string)$xml;
        return;
    }
   
$seen=array();
    foreach (
$children as $child => $value) {
       
$childname = ($child instanceof SimpleXMLElement)?$child->getName():$child;
        if ( !isset(
$seen[$childname])){
           
$seen[$childname]=0;
        }
       
$seen[$childname]++;
       
XMLToArrayFlat($value, $return, $path.'/'.$child.'['.$seen[$childname].']');
    }
}
?>

Use like this:

<?php
$xml
= simplexml_load_string(...some xml string...);
$xmlarray = array(); // this will hold the flattened data
XMLToArrayFlat($xml, $xmlarray, '', true);
?>

You can also pull multiple files in one array:

<?php
foreach($files as $file){
   
$xml = simplexml_load_file($file);
   
XMLToArrayFlat($xml, $xmlarray, $file.':', true);
}
?>
The respective filename/path is thus prefixed to each key.

kristof at viewranger dot com (18-Nov-2010 01:14)

If you tried to load an XML file with this, but the CDATA parts were not loaded for some reason, is because you should do it this way:

$xml = simplexml_load_file($this->filename, 'SimpleXMLElement', LIBXML_NOCDATA);

This converts CDATA to String in the returning object.

sherwinterunez at yahoo dot com (01-Sep-2010 07:15)

<?php

// Sherwin R. Terunez
//
// This is my own version of XML Object to Array
//

function amstore_xmlobj2array($obj, $level=0) {
   
   
$items = array();
   
    if(!
is_object($obj)) return $items;
       
   
$child = (array)$obj;
   
    if(
sizeof($child)>1) {
        foreach(
$child as $aa=>$bb) {
            if(
is_array($bb)) {
                foreach(
$bb as $ee=>$ff) {
                    if(!
is_object($ff)) {
                       
$items[$aa][$ee] = $ff;
                    } else
                    if(
get_class($ff)=='SimpleXMLElement') {
                       
$items[$aa][$ee] = amstore_xmlobj2array($ff,$level+1);
                    }
                }
            } else
            if(!
is_object($bb)) {
               
$items[$aa] = $bb;
            } else
            if(
get_class($bb)=='SimpleXMLElement') {
               
$items[$aa] = amstore_xmlobj2array($bb,$level+1);
            }
        }
    } else
    if(
sizeof($child)>0) {
        foreach(
$child as $aa=>$bb) {
            if(!
is_array($bb)&&!is_object($bb)) {
               
$items[$aa] = $bb;
            } else
            if(
is_object($bb)) {
               
$items[$aa] = amstore_xmlobj2array($bb,$level+1);
            } else {
                foreach(
$bb as $cc=>$dd) {
                    if(!
is_object($dd)) {
                       
$items[$obj->getName()][$cc] = $dd;
                    } else
                    if(
get_class($dd)=='SimpleXMLElement') {
                       
$items[$obj->getName()][$cc] = amstore_xmlobj2array($dd,$level+1);
                    }
                }
            }
        }
    }

    return
$items;
}

?>

svdmeer at xs4all dot nl (23-May-2010 07:57)

Simple XML in an array of strings without objects:

<?php
function xml2array($xml) {
   
$arXML=array();
   
$arXML['name']=trim($xml->getName());
   
$arXML['value']=trim((string)$xml);
   
$t=array();
    foreach(
$xml->attributes() as $name => $value){
       
$t[$name]=trim($value);
    }
   
$arXML['attr']=$t;
   
$t=array();
    foreach(
$xml->children() as $name => $xmlchild) {
       
$t[$name][]=xml2array($xmlchild); //FIX : For multivalued node
   
}
   
$arXML['children']=$t;
    return(
$arXML);
}
?>
[EDITOR thiago NOTE: Function has fixes and improvements by n dot dhuygelaere at oieau dot fr]

Ashok dot 893 at gmail dot com (26-Apr-2010 06:48)

This is very simple way to convert all applicable objects into associative array.  This works with not only SimpleXML but any kind of object. The input can be either array or object. This function also takes an options parameter as array of indices to be excluded in the return array. And keep in mind, this returns only the array of non-static and accessible variables of the object since using the function get_object_vars().

<?php
function objectsIntoArray($arrObjData, $arrSkipIndices = array())
{
   
$arrData = array();
   
   
// if input is object, convert into array
   
if (is_object($arrObjData)) {
       
$arrObjData = get_object_vars($arrObjData);
    }
   
    if (
is_array($arrObjData)) {
        foreach (
$arrObjData as $index => $value) {
            if (
is_object($value) || is_array($value)) {
               
$value = objectsIntoArray($value, $arrSkipIndices); // recursive call
           
}
            if (
in_array($index, $arrSkipIndices)) {
                continue;
            }
           
$arrData[$index] = $value;
        }
    }
    return
$arrData;
}
?>

Usage:

<?php
$xmlUrl
= "feed.xml"; // XML feed file/URL
$xmlStr = file_get_contents($xmlUrl);
$xmlObj = simplexml_load_string($xmlStr);
$arrXml = objectsIntoArray($xmlObj);
print_r($arrXml);
?>

michael dot allen at emp dot shentel dot com (15-Apr-2010 07:06)

Here is a very robust SimpleXML parser.  Can be used to load files, strings, or DOM into SimpleXML, or can be used to perform the reverse when handed SimpleXML.

<?php
/**
 * XMLParser Class File
 *
 * This class loads an XML document into a SimpleXMLElement that can
 * be processed by the calling application.  This accepts xml strings,
 * files, and DOM objects.  It can also perform the reverse, converting
 * an SimpleXMLElement back into a string, file, or DOM object.
 */
class XMLParser {
   
/**
     * While parsing, parse the supplied XML document.
     *
     * Sets up a SimpleXMLElement object based on success of parsing
     * the XML document file.
     *
     * @param string $doc the xml document location path
     * @return object
     */
   
public static function loadFile($doc) {
        if (
file_exists($doc)) {
            return
simplexml_load_file($doc);
        } else {
            throw new
Exception ("Unable to load the xml file " .
                                
"using: \"$doc\"", E_USER_ERROR);
        }
    }
   
/**
     * While parsing, parse the supplied XML string.
     *
     * Sets up a SimpleXMLElement object based on success of parsing
     * the XML string.
     *
     * @param string $string the xml document string
     * @return object
     */
   
public static function loadString($string) {
        if (isset(
$string)) {
            return
simplexml_load_string($string);
        } else {
            throw new
Exception ("Unable to load the xml string " .
                                
"using: \"$string\"", E_USER_ERROR);
        }
    }
   
/**
     * While parsing, parse the supplied XML DOM node.
     *
     * Sets up a SimpleXMLElement object based on success of parsing
     * the XML DOM node.
     *
     * @param object $dom the xml DOM node
     * @return object
     */
   
public static function loadDOM($dom) {
        if (isset(
$dom)) {
            return
simplexml_import_dom($dom);
        } else {
            throw new
Exception ("Unable to load the xml DOM node " .
                                
"using: \"$dom\"", E_USER_ERROR);
        }
    }
   
/**
     * While parsing, parse the SimpleXMLElement.
     *
     * Sets up a XML file, string, or DOM object based on success of
     * parsing the XML DOM node.
     *
     * @param object $path the xml document location path
     * @param string $type the return type (string, file, dom)
     * @param object $simplexml the simple xml element
     * @return mixed
     */
   
public static function loadSXML($simplexml, $type, $path) {
        if (isset(
$simplexml) && isset($type)) {
        switch (
$type) {
            case
'string':
                return
$simplexml->asXML();
            break;
            case
'file':
                if (isset(
$path)) {
                    return
$simplexml->asXML($path);
                } else {
                    throw new
Exception ("Unable to create the XML file. Path is missing or" .
                                        
"is invalid: \"$path\"", E_USER_ERROR);
                }
            break;
            case
'dom':
                return
dom_import_simplexml($simplexml);
            break;
        }
        } else {
            throw new
Exception ("Unable to load the simple XML element " .
                                
"using: \"$simplexml\"", E_USER_ERROR);
        }
    }
}
?>

emmanuel (17-Feb-2010 06:21)

dynamic sql in php using xml:

test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<sql>
    <statement>
        SELECT * FROM USERS
        <call criteria="byId">WHERE id = %d</call>
        <call criteria="byUsername">WHERE username = "%s"</call>;
    </statement>
</sql>

index.php:
<?php
function callMe($param) {
   
$search = array('byUsername' => 'dynsql');
   
    if (isset(
$search[$param[1]])) {
        return
sprintf($param[2], $search[$param[1]]);
    }
   
    return
"";
}

$xml = simplexml_load_file("test.xml");
$string = $xml->statement->asXML();
$string = preg_replace_callback('/<call criteria="(\w+)">(.*?)<\/call>/', 'callMe', $string);
$node = simplexml_load_string($string);
echo
$node;
?>

obviously, this example can be improved [in your own code.]

jakep at insperia dot com (28-Jan-2010 09:44)

If you decide to include a hyphen or a dash in the name of your attribute things get a bit interesting. The code has to be adjusted since the name of a class method cannot contain "-". To make it work, the attribute name has to include braces and single quotes (e.g. "{'name'}").

Credit http://aaronz-sakai.blogspot.com

mahmutta at gmail dot com (20-Jan-2010 08:58)

while using simple xml and get double or float int value from xml object for using math operations (+ * - / ) some errors happens on the operation, this is because of simple xml returns everythings to objects.
exmple;

<?php

$name
= "somestring";
$size = 11.45;
$xml = '
<xml>
 <name>somestring</name>
 <size>11.45</size>
</xml>'
;

 
$xmlget = simplexml_load_string($xml)

echo
$xml->size*2;    // 20  its false
// ($xml->size is an object (int)11 and  (45) )

// this is true
echo $size*2;            // 22.90
echo (float)$size*2;   // 22.90
?>

Danny from holland (03-Dec-2009 01:58)

I tested all the scripts ive found on this page but none of them wasnt working.

ive made an new script that will work and wont get any memory errors with big xml feeds

<?php
print "<pre>";

$root = simplexml_load_string($XML_URL);
$data = get_object_vars($root);

$producten = array();

foreach (
$data['product'] as $keys => $values) {
   
$producten['product'][$keys] = get_object_vars($data['product']);
   
    foreach (
$values as $key => $value) {
       
$value = str_replace("\r\n", '<br />', $value);
       
$value = str_replace("\r", '<br />', $value);
       
$value = str_replace("\n", '<br />', $value);
       
$producten['product'][$keys][$key] = $value;
    }
   
}
print_R($producten);

print
"</pre>";
?>

antoine dot rabanes at gmail dot com (16-Oct-2009 03:22)

if for some reasons you need the string value instead of the simpleXML Object you can cast the return value as a string.

exemple:

<?php
$all_api_call
= simplexml_load_file($url);
$all_api = array();
$all_api = $all_api_call->result;
$list_all_api_name = array();
$i = 0;
foreach (
$all_api->children() as $funcky_function)
{
   
$string_tmp = (string )$funcky_function->function;
   
$list_all_api_name[$i++] = $putain;
}
?>

...

spcmky at gmail dot com (14-Oct-2009 06:49)

There are issues with most examples of converting a simplexml object into an array recursively.  The situation that fails is when you have a value for an element and attributes.  For example:

<results found="yes">
  <warehouse>
    <name>WH3</name>
    <phone>2-1121</phone>
  </warehouse>
  <items count="3">
    <item id="E1120" bin="AA21">Desk</item>
    <item id="E1121" bin="FG03">Chair</item>
    <item id="E1122" bin="CD00">Table</item>
  </items>
</results>

If you :

<?php
$obj
= simplexml_load_string($xml);
print_r($obj);
?>

You will get:

(
    [@attributes] => Array
        (
            [found] => yes
        )

    [warehouse] => SimpleXMLElement Object
        (
            [name] => WH3
            [phone] => 2-1121
        )

    [items] => SimpleXMLElement Object
        (
            [@attributes] => Array
                (
                    [count] => 3
                )

            [item] => Array
                (
                    [0] => Desk
                    [1] => Chair
                    [2] => Table
                )

        )

)

Where is the rest of the data for the items?  If you were to traverse recursively through the object the item information is in fact there.  The problem is how to represent an element as an array that has a value and attributes.  Most of the solution's just ignore the attributes. 

print_r, var_dump, and get_object_vars ignore the attributes in this special case from what I've found.

Here is a simple function to convert the object into an array but it still fails to deal with the attributes.
<?php
function ToArray ( $data )
{
  if (
is_object($data)) $data = get_object_vars($data);
  return (
is_array($data)) ? array_map(__FUNCTION__,$data) : $data;
}
?>

So why even bother trying to convert the object to an array?  Simply because of serialization for caching the object.

One solution would be to create an index called "value" and assign that the element's value.  This way the attributes could coexist.

walter (12-Jun-2009 03:58)

Working fix for the infamous SimpleXML + memcache bug.

Improves code at http://tinyurl.com/bmoon-simplexml to actually work for arbitrary-depth structures.  (Because neither the function nor the json_decode(json_encode($obj)) hack listed there worked for me.)

There's probably some superfluous code in here that could be improved on -- but it works!

<?php
 
# convert a structure that may include objects to a pure
 # array-based structure (that can be stored in memcache)
 #  ... includes support for simplexml!
 # (nb: may have problems with infinite recursive structs)
 
function enforce_array($obj) {
 
$array = (array)$obj;
  if(empty(
$array)) {
  
$array = '';
  }
  else {
   foreach(
$array as $key=>$value) {
    if(!
is_scalar($value)) {
     if(
is_a($value,'SimpleXMLElement')) {
     
$tmp = memcache_objects_to_array($value);
      if(!
is_array($tmp)) {
      
$tmp = ''.$value;
      }
     
$array[$key] = $tmp;
     }
     else {
     
$array[$key] = enforce_array($value);
     }
    }
    else {
    
$array[$key] = $value;
    }
   }
  }
  return
$array;
 }
?>

mail at kleineedv dot de (28-Apr-2009 08:37)

I had a problem with simplexml reading nodes from an xml file. It always return an SimpleXML-Object but not the text inside the node.

Example:
<?xml version="1.0" encoding="UTF-8"?>
<Test>
    <Id>123</Id>
</Test>

Reading this xml into a variable called $xml and then doing the following
<?php
$myId
= $xml->Id;
?>
Did not return 123 in $myId, but instead I got a SimpleXMLElement Object.

The solution is simple, when you know it. Use explicit string conversion.
<?php
$myId
= (string)$xml->Id;
?>

oscargodson at gmail dot com (25-Jan-2009 11:05)

To add to what others have said, you can't directly put a $_GET or $_POST value into a variable then into an attribute using SimpleXML. You must first convert it to an integer.

This will NOT work

<?php
      $page_id
= $_GET['id'];
      echo
$xml->page[$page_id]
?>

You will get something like:
Notice: Trying to get property of non-object in /Applications/MAMP/htdocs/mysite/index.php on line 10

However, this WILL work and is much simpler then using (string) or other methods.
<?php
   $page_id
= intval($_GET['id']);
   echo
$xml->page[$page_id]
?>

bxt at die-optimisten dot net (26-Nov-2008 03:47)

Addition to QLeap's post:
SimpleXML will return a reference to an object containing the node value and you can't use references in session variables as there is no feasible way to restore a reference to another variable.

This won't work too:
$val=$this->xml->node->attributes()->name;
echo $array[$val]; // will cause a warning because of the wrong index type.

You have to convert/cast to a String first:
echo $array[(string)$val];

This will work as expected, because converting will call the __toString() method. Therefor echo works too:
echo $val; // will display the name

QLeap (18-Nov-2008 10:27)

Storing SimpleXMLElement values in $_SESSION does not work. Saving the results as an object or individual elements of the object will result in the dreaded "Warning: session_start() [function.session-start]: Node no longer exists" error.

For example, this does not work:

    $xml  = new SimpleXMLElement($page);
    $country  = $xml->Response->Placemark->AddressDetails->Country->CountryNameCode;
    $_SESSION['country'] = $country;

This will work:

    $_SESSION['country'] = (string) $country;

gwhitescarver at yahoo dot com (11-Sep-2008 09:02)

Moving some code from a PHP 5.2.6 / Windows environment to a 5.2.0 / Linux environment, I somehow lost access to a plain text node within a SimpleXML Object.  On a var_dump of $xml_node, a [0] element was shown as the string '12'.  However, $xml_node[0] was evaluating NULL in 5.2.0.  You can see below the code change I made, pulling my data out of the raw XML with a regular expression.  Hope this is useful to someone.

//In some versions of PHP it seems we cannot access the [0] element of a SimpleXML Object.  Doesn't work in 5.2.0:
//$count = $xml_node[0];
//grab the raw XML:
$count = ($xml_node->asXML());
//pull out the number between the closing and opening brace of the xml:
$count = preg_replace('/.*>(\d*)<.*/', '$1', $count);

charlie at blankcanvasstudios dot com (14-Aug-2008 07:21)

Optimizing aalaap at gmail dot com's php

<?php
function is_rss($feedxml) {
    @
$feed = simplexml_load_string($feedxml);

    return (
$feed->channel->item)?true:false;
}

function
is_atom($feedxml) {
    @
$feed = new SimpleXMLElement($feedxml);
    (
$feed->entry):true:false;
}
?>

aalaap at gmail dot com (30-Jun-2008 02:58)

Here are two quick and dirty functions that use SimpleXML to detect if a feed xml is RSS or ATOM:

<?php
function is_rss($feedxml) {
    @
$feed = new SimpleXMLElement($feedxml);

    if (
$feed->channel->item) {
        return
true;
    } else {
        return
false;
    }
}

function
is_atom($feedxml) {
    @
$feed = new SimpleXMLElement($feedxml);

    if (
$feed->entry) {
        return
true;
    } else {
        return
false;
    }
}
?>

The functions take in the full text feed (retrieved via cURL, for example) and return a true or a false based on the result.