simplexml_load_string
Takes a well-formed XML string and returns it as an object.
Parameters
You may use this optional parameter so that simplexml_load_string() will return an object of the specified class. That class should extend the SimpleXMLElement class.
Since Libxml 2.6.0, you may also use the options parameter to specify additional Libxml parameters.
true if namespace_or_prefix is a prefix, false if it’s a URI; defaults to false .
Return Values
Returns an object of class SimpleXMLElement with properties containing the data held within the xml document, or false on failure.
This function may return Boolean false , but may also return a non-Boolean value which evaluates to false . Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
Errors/Exceptions
Produces an E_WARNING error message for each error found in the XML data.
Use libxml_use_internal_errors() to suppress all XML errors, and libxml_get_errors() to iterate over them afterwards.
Examples
Example #1 Interpret an XML string
$xml = simplexml_load_string ( $string );
The above example will output:
SimpleXMLElement Object ( [title] => Forty What? [from] => Joe [to] => Jane [body] => I know that's the answer -- but what's the question? )
At this point, you can go about using $xml->body and such.
See Also
- simplexml_load_file() — Interprets an XML file into an object
- SimpleXMLElement::__construct() — Creates a new SimpleXMLElement object
- Dealing with XML errors
- libxml_use_internal_errors() — Disable libxml errors and allow user to fetch error information as needed
- Basic SimpleXML usage
User Contributed Notes 22 notes
I had a hard time finding this documented, so posting it here in case it helps someone:
If you want to use multiple libxml options, separate them with a pipe, like so:
$xml = simplexml_load_string ( $string , ‘SimpleXMLElement’ , LIBXML_NOCDATA | LIBXML_NOBLANKS );
?>
A simpler way to transform the result into an array (requires json module).
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.
$xml = simplexml_load_string ( ‘
print_r ( $xml );
/*
SimpleXMLElement Object
(
[0] => Text1 & XML entities
)
*/
$xml2 = simplexml_load_string ( ‘ ‘ );
print_r ( $xml2 );
/*
SimpleXMLElement Object
(
)
*/
// Where’s my CDATA?
// Let’s try explicit casts
print_r ( (string) $xml );
print_r ( (string) $xml2 );
/*
Text1 & XML entities
Text2 & raw data
*/
// Much better
?>
As was said before don’t use var_dump() or print_r() to see SimpleXML object structure as they do not returns always what you expect.
Consider the following:
// load xml into SimpleXML object
$xml = simplexml_load_string ( $xml_txt , ‘SimpleXMLElement’ , LIBXML_NOCDATA ); //LIBXML_NOCDATA LIBXML_NOWARNING
// see object structure
print_r ( $xml );
/* this prints
SimpleXMLElement Object
(
[folder] => Array
(
[0] => aaaa
[1] => bbbb
)
// but.
foreach ( $xml -> folder as $value ) <
print_r ( $value );
>
/* prints complete structure of each folder element:
SimpleXMLElement Object
(
[@attributes] => Array
(
[ID] => 65
[active] => 1
[permission] => 1
)
SimpleXMLElement Object
(
[@attributes] => Array
(
[ID] => 65
[active] => 1
[permission] => 1
)
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.
$simplexml = simplexml_load_string ( $xml );
// This prints «Parse Error».
echo ( $simplexml ? ‘Valid XML’ : ‘Parse Error’ ), PHP_EOL ;
// But this prints «There’s stuff here», proving that
// the SimpleXML object was created successfully.
echo $simplexml -> children ( ‘http://example.com/custom’ )-> Node , PHP_EOL ;
// Use this instead:
echo ( $simplexml !== FALSE ? ‘Valid XML’ : ‘Parse Error’ ), PHP_EOL ;
A simple extension that adds a method for retrieving a specific attribute:
class simple_xml_extended extends SimpleXMLElement
public function Attribute ( $name )
foreach( $this -> Attributes () as $key => $val )
if( $key == $name )
return (string) $val ;
>
>
echo $xml -> dog -> Attribute ( ‘type’ );
I prefer to use this technique rather than typecasting attributes.
Please note that not all LIBXML options are supported with the options argument.
For instance LIBXML_XINCLUDE does not work. But there is however a work around:
$xml = new DOMDocument ();
$xml -> loadXML ( $XMLString );
$xml -> xinclude ();
$xml = simplexml_import_dom ( $xml );
It doesn’t seem to be documented anywhere, but you can refer to an element «value» for the purpose of changing it like so:
$xml -> number -> < 0 >= $xml -> number -> < 0 >+ 1 ;
However, this only works with a direct assignment, not with any of the other operators:
$xml -> number -> < 0 >+= 1 ;
// Or:
$xml -> number ->< 0 >++;
echo $xml -> asXml ();
?>
Both of the above cases would result in:
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( strpos ( $content , ‘ >
$content = preg_replace_callback (
‘##’ ,
‘parseCDATA’ ,
str_replace ( «\n» , » » , $content )
);
>
?>
I wanted to convert an array containing strings and other arrays of the same type into a simplexml object.
Here is the code of the function array2xml that I’ve developed to perform this conversion. Please note that this code is simple without any checks.
function array2xml ( $array , $tag )
function ia2xml ( $array ) <
$xml = «» ;
foreach ( $array as $key => $value ) <
if ( is_array ( $value )) <
$xml .= «< $key >» . ia2xml ( $value ). «$key>» ;
> else <
$xml .= «< $key >» . $value . «$key>» ;
>
>
return $xml ;
>
return simplexml_load_string ( «< $tag >» . ia2xml ( $array ). «$tag>» );
>
$test [ ‘type’ ]= ‘lunch’ ;
$test [ ‘time’ ]= ’12:30′ ;
$test [ ‘menu’ ]=array( ‘entree’ => ‘salad’ , ‘maincourse’ => ‘steak’ );
echo array2xml ( $test , «meal» )-> asXML ();
?>
The XML2Array func now Recursive!
function XML2Array ( $xml , $recursive = false )
if ( ! $recursive )
$array = simplexml_load_string ( $xml ) ;
>
else
$array = $xml ;
>
$newArray = array () ;
$array = ( array ) $array ;
foreach ( $array as $key => $value )
$value = ( array ) $value ;
if ( isset ( $value [ 0 ] ) )
$newArray [ $key ] = trim ( $value [ 0 ] ) ;
>
else
$newArray [ $key ] = XML2Array ( $value , true ) ;
>
>
return $newArray ;
>
?>
Here is my update to Bob’s simple SimpleXML wrapper function.
I noticed his version would turn an empty SimpleXMLElement into an empty array.
/**
* http://php.net/manual/en/function.simplexml-load-string.php#91564
*
* 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
*
* @param $input
* @param null $callback
* @param bool $recurse
* @return array|mixed
*
*/
function unserialize_xml ( $input , $callback = null , $recurse = false )
// 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 array
if ( $data instanceof SimpleXMLElement ) if(!empty( $data )) $data = (array) $data ;
> else $data = » ;
>
>
// Recurse into arrays
if ( is_array ( $data )) foreach ( $data as & $item ) $item = unserialize_xml ( $item , $callback , true );
// Run callback and return
return (! is_array ( $data ) && is_callable ( $callback ))? call_user_func ( $callback , $data ): $data ;
>
?>
$xml = json_decode ( json_encode ((array) simplexml_load_string ( $string )), 1 );
?> A reminder that json_encode attempts to convert data to UTF-8 without specific knowledge of the source encoding. This method can cause encoding issues if you’re not working in UTF-8.?php
If you want to set the charset of the outputed xml, simply set the encoding attribute like this :
‘ ); ?> The generated xml outputed by $xml->asXML will containt accentuated characters like ‘é’ instead of é.
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).
function 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 array
if ( $data instanceof SimpleXMLElement ) $data = (array) $data ;
// Recurse into arrays
if ( is_array ( $data )) foreach ( $data as & $item ) $item = unserialize_xml ( $item , $callback , true );
// Run callback and return
return (! is_array ( $data ) && is_callable ( $callback ))? call_user_func ( $callback , $data ): $data ;
>
?>
The parsing of XML-data will stop when reaching character 0.
Please avoid this character in your XML-data.
php parse xml string [duplicate]
For those situations where SimpleXML is not available, I use this function originally posted in a comment on php.net. It works great 99% of the time.
if ($x_level!=1 && $x_type == 'complete') < if ($_tmp==$x_tag) $multi_key[$x_tag][$x_level]=1; $_tmp=$x_tag; >> // jedziemy po tablicy foreach ($vals as $xml_elem) < $x_tag=$xml_elem['tag']; $x_level=$xml_elem['level']; $x_type=$xml_elem['type']; if ($x_type == 'open') $level[$x_level] = $x_tag; $start_level = 1; $php_stmt = '$xml_array'; if ($x_type=='close' && $x_level!=1) $multi_key[$x_tag][$x_level]++; while ($start_level < $x_level) < $php_stmt .= '[$level['.$start_level.']]'; if (isset($multi_key[$level[$start_level]][$start_level]) && $multi_key[$level[$start_level]][$start_level]) $php_stmt .= '['.($multi_key[$level[$start_level]][$start_level]-1).']'; $start_level++; >$add=''; if (isset($multi_key[$x_tag][$x_level]) && $multi_key[$x_tag][$x_level] && ($x_type=='open' || $x_type=='complete')) < if (!isset($multi_key2[$x_tag][$x_level])) $multi_key2[$x_tag][$x_level]=0; else $multi_key2[$x_tag][$x_level]++; $add='['.$multi_key2[$x_tag][$x_level].']'; >if (isset($xml_elem['value']) && trim($xml_elem['value'])!='' && !array_key_exists('attributes', $xml_elem)) < if ($x_type == 'open') $php_stmt_main=$php_stmt.'[$x_type]'.$add.'[\'content\'] = $xml_elem[\'value\'];'; else $php_stmt_main=$php_stmt.'[$x_tag]'.$add.' = $xml_elem[\'value\'];'; eval($php_stmt_main); >if (array_key_exists('attributes', $xml_elem)) < if (isset($xml_elem['value'])) < $php_stmt_main=$php_stmt.'[$x_tag]'.$add.'[\'content\'] = $xml_elem[\'value\'];'; eval($php_stmt_main); >foreach ($xml_elem['attributes'] as $key=>$value) < $php_stmt_att=$php_stmt.'[$x_tag]'.$add.'[$key] = $value;'; eval($php_stmt_att); >> > return $xml_array; > ?>
If you’re familiar with the Zend Framework, pass your XML to Zend_Config_Xml
$myXml = ' value value - 1
- 2
- 3
';
$xml = new Zend_Config_Xml( $myXml ); $var = $xml->var; $nestedVar = $xml->nested->var; $arrayVar = $xml->arrayVar->toArray();
Zend Config XML uses simplexml and builds on this to give a nice interface, that makes it really easy to get to the xml node you’re looking for.
There’s loads more in the ZF Manual, including how to access attributes, and some other really useful features.
Zend Config is one of the easiest to use parts of ZF, and (I think) it’s a standalone component, you can use just Zend Config and no other part of ZF