|
simplexml_load_file
Interprets an XML file into an object
(PHP 5)
Example 2262. Interpret an XML document<?php This script will display, on success: SimpleXMLElement Object
At this point, you can go about using Related Examples ( Source code ) » simplexml load file Examples ( Source code ) » File based login Examples ( Source code ) » fgetss Gets line from file pointer and strip HTML tags Examples ( Source code ) » Use simplexml_load_file to load xml file Examples ( Source code ) » XML file dump Examples ( Source code ) » simplexml_load_file Examples ( Source code ) » XML file validation Examples ( Source code ) » Print all files under a directory Examples ( Source code ) » Close a file after reading Examples ( Source code ) » Rename() function for moving files Examples ( Source code ) » Delete a file Examples ( Source code ) » File existance Examples ( Source code ) » Checking That a File Exists Examples ( Source code ) » Is it a file Examples ( Source code ) » Is the file a directory Examples ( Source code ) » Is the file readable Code Examples / Notes » simplexml load fileanonymous
What has been found when using the script is that simplexml_load_file() will remove any HTML formating inside the XML file, and will also only load so many layers deep. If your XML file is to deap, it will return a boolean false.
wouter
To correctly extract a value from a CDATA just make sure you cast the SimpleXML Element to a string value by using the cast operator: $xml = '<?xml version="1.0" encoding="UTF-8" ?> <rss> <channel> <item> <title><![CDATA[Tom & Jerry]]></title> </item> </channel> </rss>'; $xml = simplexml_load_string($xml); // echo does the casting for you echo $xml->channel->item->title; // but vardump (or print_r) not! var_dump($xml->channel->item->title); // so cast the SimpleXML Element to 'string' solve this issue var_dump((string) $xml->channel->item->title); Above will output: Tom & Jerry object(SimpleXMLElement)#4 (0) {} string(11) "Tom & Jerry" info
The object2array function by joelfielder is very nice but fails for CDATA. Very simple fix: <? function object2array($object) { $return = NULL; if(is_array($object)) { foreach($object as $key => $value) $return[$key] = object2array($value); } else { $var = get_object_vars($object); if($var) { foreach($var as $key => $value) $return[$key] = object2array($value); } else return strval($object); // strval and everything is fine } return $return; } ?> skutter
So it seems SimpleXML doesn't support CDATA... I bashed together this little regex function to sort out the CDATA before trying to parse XML with the likes of simplexml_load_file / simplexml_load_string. Hope it might help somebody and would be very interested to hear of better solutions. (Other than *not* using SimpleXML of course! ;) It looks for any <![CDATA [Text and HTML etc in here]]> elements, htmlspecialchar()'s the encapsulated data and then strips the "<![CDATA [" and "]]>" tags out. <?php function simplexml_unCDATAise($xml) { $new_xml = NULL; preg_match_all("/\<\!\[CDATA \[(.*)\]\]\>/U", $xml, $args); if (is_array($args)) { if (isset($args[0]) && isset($args[1])) { $new_xml = $xml; for ($i=0; $i<count($args[0]); $i++) { $old_text = $args[0][$i]; $new_text = htmlspecialchars($args[1][$i]); $new_xml = str_replace($old_text, $new_text, $new_xml); } } } return $new_xml; } //Usage: $xml = 'Your XML with CDATA...'; $xml = simplexml_unCDATAise($xml); $xml_object = simplexml_load_string($xml); ?> patrick
simplexml_load_file creates an xml-tree with values that are UTF-8 strings. To convert them to the more common encoding ISO-8859-1 (Latin-1), use "utf8_decode". pa ul
One thing to note about the object2array function from aleshru below... this function doesn't handle CDATA fields (e.g. a poorly formed HTML formatted message.) It just returns an empty array. example XML: --------------8<--------------- <note> <subject>HTML Message Dude!</subject> <content><![CDATA[ <B> this is some </b> CDATA data that is useful to handle or at least see. <div> it doesn't matter that the HTML isn't properly </di>v opened or closed. the html content is still continuing!!]]></content> </note> --------------8<--------------- the simpleXML built in functionality seems to handle this just dandily however. <?php $object = simplexml_load_string($that_string_of_xml_above); echo ((string) $object->content); /* OUTPUT: <B> this is some </b> CDATA data that is useful to handle or at least see. <div> it doesn't matter that the HTML isn't properly </di>v opened or closed. the html content is still continuing!! */ ?> This object2array function does work well for the other types of xml content however. bart verkoeijen
No problems at all with CDATA: Test.xml: <?xml version="1.0" encoding="iso-8859-1"?> <xml> <cdata><![CDATA[abc abc]]></cdata> </xml> PHP Code: <?php $xml = simplexml_load_file( 'test.xml' ); echo $xml->cdata; ?> Output: > X-Powered-By: PHP/5.1.1 > Content-type: text/html > > abc abc The problem below is probably caused by incorrect syntax. It's "<![CDATA[]]>" instead of "<![CDATA []]>" (note the space). genialbrainmachine
Micro$oft Word uses non-standard characters and they create problems in using simplexml_load_file. Many systems include non-standard Word character in their implementation of ISO-8859-1. So an XML document containing that characters can appear well-formed (i.e.) to many browsers. But if you try to load this kind of documents with simplexml_load_file you'll have a little bunch of troubles.. I believe that this is exactly the same question discussed in htmlentites. Following notes to htmlentitles are interesting here too (given in the reverse order, to grant the history): http://it.php.net/manual/en/function.htmlentities.php#26379 http://it.php.net/manual/en/function.htmlentities.php#41152 http://it.php.net/manual/en/function.htmlentities.php#42126 http://it.php.net/manual/en/function.htmlentities.php#42511 joelfielder
In the object2array function posted above, the following data structure would be left unchanged: Array ( [0] => Object Object ( [var] => 1 ) ) The simplexml_load_... functions return structures similar to the above, a simple example: SimpleXMLElement Object ( [USERS] => Array ( [0] => SimpleXMLElement Object ( [NAME] => Joel Fielder [EMAIL] => joelfielder@hotmail.com ) ) ) In order to store such information in the session, we have to convert all of the SimpleXMLElement objects present in the structure: Array ( [USERS] => Array ( [0] => Array ( [NAME] => Joel Fielder [EMAIL] => joelfielder@hotmail.com ) ) ) And here is the code to do so: <?php function object2array($object) { $return = NULL; if(is_array($object)) { foreach($object as $key => $value) $return[$key] = object2array($value); } else { $var = get_object_vars($object); if($var) { foreach($var as $key => $value) $return[$key] = object2array($value); } else return $object; } return $return; } ?> kyle
In regards to Anonymous on 7th April 2006 There is a way to get back HTML tags. For example: <?xml version="1.0"?> <intro> Welcome to <b>Example.com</b>! </intro> <?php // I use @ so that it doesn't spit out content of my XML in an error message if the load fails. The content could be passwords so this is just to be safe. $xml = @simplexml_load_file('content_intro.xml'); if ($xml) { // asXML() will keep the HTML tags but it will also keep the parent tag <intro> so I strip them out with a str_replace. You could obviously also use a preg_replace if you have lots of tags. $intro = str_replace(array('<intro>', '</intro>'), '', $xml->asXML()); } else { $error = "Could not load intro XML file."; } ?> With this method someone can change the intro in content_intro.xml and ensure that the HTML is well formed and not ruin the whole site design. mark
If the property of an object is empty the array is not created. Here is a version object2array that transfers properly. function object2array($object) { $return = NULL; if(is_array($object)) { foreach($object as $key => $value) $return[$key] = object2array($value); } else { $var = get_object_vars($object); if($var) { foreach($var as $key => $value) $return[$key] = ($key && !$value) ? NULL : object2array($value); } else return $object; } return $return; } aleshru
I've got function to convert SimpleXmlObject's to array. <?php function object2array ( $object ) { if ( !is_object ( $object ) ) return $object; $return = array (); $var = get_object_vars ( $object ); while ( list ( $k, $v ) = each ( $var ) ) $return [ $k ] = object2array ( $v ); return $return; } class dummy{ var $a = 1; var $b = 2; var $c = 3; function __construct(){ $this->d = new dummy2(); } } class dummy2{ function __construct(){ $this->e = 'f'; $this->true = true; $this->false = false; $this->null = null; $this->file = __FILE__; } } $object = new dummy; $arr = object2array($object); echo "<pre>"; print_r($arr); echo "</pre>"; ?> fdouteaud
Be careful if you are using simplexml data directly to feed your MySQL database using MYSQLi and bind parameters. The data coming from simplexml are Objects and the bind parameters functions of MySQLi do NOT like that! (it causes some memory leak and can crash Apache/PHP) In order to do this properly you MUST cast your values to the right type (string, integer...) before passing them to the binding methods of MySQLi. I did not find that in the documentation and it caused me a lot of headache. |
Change LanguageSimpleXMLElement->addAttribute() SimpleXMLElement->addChild() SimpleXMLElement->asXML() SimpleXMLElement->attributes() SimpleXMLElement->children() SimpleXMLElement->__construct() SimpleXMLElement->getDocNamespaces() SimpleXMLElement->getName() SimpleXMLElement->getNamespaces() SimpleXMLElement->registerXPathNamespace() SimpleXMLElement->xpath() simplexml_import_dom simplexml_load_file simplexml_load_string |