PHP Doku:: Übersetzt ein XML-File in ein Objekt - function.simplexml-load-file.html

Verlauf / Chronik / History: (30) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzXML-ManipulationSimpleXMLSimpleXML-Funktionensimplexml_load_file

Ein Service von Reinhard Neidl - Webprogrammierung.

SimpleXML-Funktionen

<<simplexml_import_dom

simplexml_load_string>>

simplexml_load_file

(PHP 5)

simplexml_load_file Übersetzt ein XML-File in ein Objekt

Beschreibung

object simplexml_load_file ( string $filename [, string $class_name = "SimpleXMLElement" [, int $options = 0 [, string $ns [, bool $is_prefix = false ]]]] )

Die Funktion wandelt das übergebene wohlgeformte (well-formed) XML-Dokument in ein Objekt um.

Parameter-Liste

filename

Pfad zur XML-Datei.

Hinweis:

Libxml 2 demaskiert den URI, wollen Sie also zum Beispiel b&c als Wert für den URI Parameter a verwenden, müssen Sie die Funktion wie folgt aufrufen: simplexml_load_file(rawurlencode('http://example.com/?a=' . urlencode('b&c'))). Seit PHP 5.1.0 wird Ihnen dieser Schritt von PHP abgenommen.

class_name

Sie können den optionalen Parameter class_name verwenden, wenn simple_load_file() ein Objekt der spezifischen Klasse zurückgeben soll. Die gewählte Klasse sollte von der Klasse SimpleXMLElement abgeleitet sein.

options

Seit PHP 5.1.0 und Libxml 2.6.0 können Sie zusätzlich den Parameter options verwenden, um weitere Libxml-Parameter anzugeben.

ns

is_prefix

Rückgabewerte

Gibt ein object der Klasse SimpleXMLElement zurück, dessen Eigenschaften die Daten des XML-Dokuments enthalten. Im Fehlerfall wird FALSE zurückgegeben.

Fehler/Exceptions

Generiert eine Fehlermeldung vom Typ E_WARNING für jeden in den XML-Daten gefundenen Fehler.

Tipp

Verwendet libxml_use_internal_errors(), um alle XML-Fehlermeldungen auszublenden, und libxml_get_errors(), um danach darüber zu iterieren.

Beispiele

Beispiel #1 Ein XML-Dokument auswerten

<?php
// Die Datei test.xml enthält ein XML-Dokument mit einem Wurzel-Element
// und mindestens einem Element /[root]/title.

if (file_exists('test.xml')) {
    
$xml simplexml_load_file('test.xml');

    
print_r($xml);
} else {
    exit(
'Konnte test.xml nicht öffnen.');
}
?>

Das Skript gibt nach erfolgreichem Laden folgendes aus:

SimpleXMLElement Object
(
  [title] => Beispiel-Titel
  ...
)

Ab diesem Punkt können Sie $xml->title und andere Elemente verwenden.

Siehe auch


23 BenutzerBeiträge:
- Beiträge aktualisieren...
guego dot ol at ig dot com dot br
13.11.2010 0:26
Analyze fully XML.

<?php
$xml
= simplexml_load_file('file.xml');

foreach(
$xml as $key0 => $value){
echo
"..1..[$key0] => $value";
foreach(
$value->attributes() as $attributeskey0 => $attributesvalue1){
echo
"________[$attributeskey0] = $attributesvalue1";
}
echo
'<br />';
////////////////////////////////////////////////
foreach($value as $key => $value2){
echo
"....2.....[$key] => $value2";
foreach(
$value2->attributes() as $attributeskey => $attributesvalue2){
echo
"________[$attributeskey] = $attributesvalue2";
}
echo
'<br />';
////////////////////////////////////////////////
foreach($value2 as $key2 => $value3){
echo
".........3..........[$key2] => $value3";
foreach(
$value3->attributes() as $attributeskey2 => $attributesvalue3){
echo
"________[$attributeskey2] = $attributesvalue3";
}
echo
'<br />';
////////////////////////////////////////////////
foreach($value3 as $key3 => $value4){
echo
"...................4....................[$key3] => $value4";
foreach(
$value4->attributes() as $attributeskey3 => $attributesvalue4){
echo
"________[$attributeskey3] = $attributesvalue4";
}
echo
'<br />';
////////////////////////////////////////////////
foreach($value4 as $key4 => $value5){
echo
".....................5......................[$key4] => $value5";
foreach(
$value5->attributes() as $attributeskey4 => $attributesvalue5){
echo
"________[$attributeskey4] = $attributesvalue5";
}
echo
'<br />';
////////////////////////////////////////////////
foreach($value5 as $key5 => $value6){
echo
"......................6.......................[$key5] => $value6";
foreach(
$value6->attributes() as $attributeskey5 => $attributesvalue6){
echo
"________[$attributeskey5] = $attributesvalue6";
}
echo
'<br />';
}}}}}
echo
'<br />';
}
?>
raduispas at gmail dot com
21.10.2010 15:12
if you want to check when this function fails,make sure to compare the return value with ===  instead of == :

<?php
$url
= 'http://www.example.com';
$xml = simpleXML_load_file($url,"SimpleXMLElement",LIBXML_NOCDATA);
if(
$xml ===  FALSE)
{
  
//deal with error
}
else {
//do stuff }
?>

Otherwise you may end up with FALSE all the time even if the document is ok. Hope this helps someone ;)
jamie at splooshmedia dot co dot uk
31.03.2010 16:17
A wrapper around simplexml_load_file to circumvent nasty error messages when the xml server times out or gives a 500 error etc.

<?php
function loadXML2($domain, $path, $timeout = 30) {

   
/*
        Usage:
       
        $xml = loadXML2("127.0.0.1", "/path/to/xml/server.php?code=do_something");
        if($xml) {
            // xml doc loaded
        } else {
            // failed. show friendly error message.
        }
    */

   
$fp = fsockopen($domain, 80, $errno, $errstr, $timeout);
    if(
$fp) {
       
// make request
       
$out = "GET $path HTTP/1.1\r\n";
       
$out .= "Host: $domain\r\n";
       
$out .= "Connection: Close\r\n\r\n";
       
fwrite($fp, $out);
       
       
// get response
       
$resp = "";
        while (!
feof($fp)) {
           
$resp .= fgets($fp, 128);
        }
       
fclose($fp);
       
// check status is 200
       
$status_regex = "/HTTP\/1\.\d\s(\d+)/";
        if(
preg_match($status_regex, $resp, $matches) && $matches[1] == 200) {   
           
// load xml as object
           
$parts = explode("\r\n\r\n", $resp);   
            return
simplexml_load_string($parts[1]);               
        }
    }
    return
false;
   
}
?>
Smokey
15.03.2010 7:16
for nested and same name values i'v made up this little bit for getting and displaying multiable values from google's geocode when a exact match is not found it returns all close matches in the following format(this is an abriged version of there output)

<Response>
  <Placemark id="1">
    <address> New York 24, NY, USA</address>
    <AddressDetails>
      ..................
    </AddressDetails>
    <Point>
      <coordinates>-73.5850086,40.7207442,0</coordinates>
    </Point>
  </Placemark>
  <Placemark id="2">
    <address>New York 27, NY, USA</address>
    <AddressDetails>
      ...................
    </AddressDetails>
    <Point>
      <coordinates>-72.8987835,40.8003588,0</coordinates>
    </Point>
  </Placemark>
  <Placemark id="3">
    <address>Cedar Place School, 20 Cedar Pl, Yonkers, NY 10705, USA</address>
    <AddressDetails>
      ..................
    </AddressDetails>
    <Point>
      <coordinates>-73.8966320,40.9256520,0</coordinates>
    </Point>
  </Placemark>
</Response>

<?php
// get and breakdown the results then store them in $var's
$Address = "99999 parkplace, new york, NY";
$urladdress = urlencode($Address);
$Base_url = "http://maps.google.com/maps/geo?q=";
$urlParts = "&output=xml";
$urlrequest = $Base_url . $urladdress . $urlParts;
$xml = simplexml_load_file($urlrequest);
$num = "0";
foreach (
$xml->Response->Placemark as $value){
   
$num++;
   
$GeoFindAdd{$num} = $value->address;
   
$GeoFindCords{$num} = $value->Point->coordinates;
}

// a simple display for the results
echo "Found ",$num," Possable Geo Data Sets <br>";
$CountNumResults = "0";
for ( ;
$num > 0; $num--){
   
$CountNumResults++;
    echo
$countnum,"<br> Address = ",$GeoFindAdd{$num},"<br> Coordinates = ",$GeoFindCords{$num},"<br>";
}
echo
"END";
?>
knl at bitflop dot com
11.09.2009 21:02
If you need to parse the data from SimpleXML into a session variable remember to define the data as a string first.

If you don't you will get warnings of "Node no longer exists" pointing to your session_start() function.

This will work:

<?php

    $new_version
= simplexml_load_file('http://example.com/version.xml');
   
$_SESSION['current_version'] = (string)$new_version->version;

?>
neil art neilanddeb dort com
17.08.2009 15:00
Because the encoding of my XML file is UTF-8 and the
encoding of my web page is iso-8859-1 I was getting strange characters such as ’ instead of a right single quote.

The solution to this turned out to be hard to find, but really easy to implement.

http://uk3.php.net/manual/en/function.iconv.php

Using the iconv() function you can convert from one encodign to another, the TRANSLIT option seems to work best for what I needed.  Here's my example:

<?php
// convert string from utf-8 to iso8859-1
$horoscope = iconv( "UTF-8", "ISO-8859-1//TRANSLIT", $horoscope );
?>

I found the solution on this page...
http://tinyurl.com/lm39xc
Hope this helps
christoph dot burgdorfer at gmail dot com
31.01.2009 21:30
This function gets RSS Items of a Wordpress blog from a search and fills the respective elements  into an array:

<?php

function get_rss_items($searchkeywords) {
   
// define url
   
$url = "http://some.wordpress.blog.com/feed/?s=" . urlencode($searchkeywords) . "&submit=";
   
   
// retrieve search results
   
if($xml = simplexml_load_file($url, 'SimpleXMLElement', LIBXML_NOCDATA)) {
       
$result["title"]   = $xml->xpath("/rss/channel/item/title");
       
$result["link"]    = $xml->xpath("/rss/channel/item/link");
       
$result["content"] = $xml->xpath("/rss/channel/item/content:encoded/text()");

        foreach(
$result as $key => $attribute) {
           
$i=0;
            foreach(
$attribute as $element) {
               
$ret[$i][$key] = (string)$element;
               
$i++;
            }
        }   
        return
$ret;   
    } else
        return
false;   
}

?>
cryonyx at cerebrate dot ru
21.10.2008 12:34
In case you have a XML file with a series of equally named elements on one level simplexml incorrectly processes them and doesn't allow to walk through the array using foreach(). As far as I'm concerned, it is the problem caused by PHP xml_parser (see: http://ru2.php.net/manual/ru/function.xml-parser-create.php#53188).

To avoid this, just use count() and walk through the array using for().

Example:

<params>
  <param>
    <name>version.shell</name>
    <value>1.0</value>
  </param>
  <param>
      <name>version.core</name>
      <value>1.0</value>
  </param>
  <param>
      <name>file.lang</name>
      <value>vc.lang</value>
  </param>
  ...
</params>

<?php
$filename
= '...';
$xml = simplexml_load_file($filename);
$p_cnt = count($xml->param);
for(
$i = 0; $i < $p_cnt; $i++) {
 
$param = $xml->param[$i];
  ...;
}
?>
mario
2.09.2008 11:08
If you want CDATA in your object you should use LIBXML_NOCDATA

<?php
$xml
= simplexml_load_file($file_xml, 'SimpleXMLElement',LIBXML_NOCDATA);
   
   
print_r($xml);
?>
clarke DOT chris at googley mail DOT com
26.07.2008 5:33
For clarification, finding attributes seems easier this way, hope I'm not being redundant.

Source XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body type="small" important="low">Don't forget me this weekend!</body>
</note>

Code Example:
<?php
$xml
= simplexml_load_file("test.xml");
print
$xml->body['type'];
?>

Output:
small
pc_storm at abv dot bg
20.05.2008 14:16
You can avoid easily, the unpredictable destruction of $_SESSION when loading a simple_xml object (which occurs under _some_ PHP versions) by serializing and unserializing it:

<?php
$oldsession
=serialize($_SESSION);
$myxml=@simplexml_load_file('my.xml');
$_SESSION=unserialize($oldsession);
unset (
$oldsession);
?>

This worked for me under PHP 5.2.5 while on 5.1.6 there was no need for such workaround at all.

Same workaround should help if there are other superglobals affected by this bug...
l [DOT] anzinger [AT] gmail [DOT] com
26.03.2008 18:03
If you don't want that the CDATA values get escaped, just load the XML with LIBXML_NOCDATA as an 3rd argument.

Note: A PHP version >= 5.1.0 is required for this to work.

Example:

<?php simplexml_load_file('xmldatei.xml', null, LIBXML_NOCDATA); ?>
php at werner dash ott dot de
29.03.2007 11:13
Making SimpleXMLElement objects session save.

Besides the effect of not surviving sessions, the SimpleXMLElement object may even crash the session_start() function when trying to re-enter the session!

To come up with a solution for this, I used a pattern as follows. The core idea is to transform the SimpleXMLElement between session calls to and from a string representation which of course is session save.

<?php
 
//
  // session save handling of SimpleXMLElement objects
  // (applies to/ tested with PHP 5.1.5 and PHP 5.2.1)
  // The myClass pattern allows for conveniently accessing
  // XML structures while being session save
  //
 
class myClass
 
{
    private
$o_XMLconfig = null;
    private
$s_XMLconfig = '';
   
    public function
__construct($args_configfile)
    {
     
$this->o_XMLconfig = simplexml_load_file($args_configfile);
     
$this->s_XMLconfig = $this->o_XMLconfig->asXML();
    }
// __construct()
   
   
public function __destruct()
    {
     
$this->s_XMLconfig = $this->o_XMLconfig->asXML();
      unset(
$this->o_XMLconfig); // this object would otherwise crash
                                 // the subsequent call of
                                 // session_start()!
   
} // __destruct()
   
   
public function __wakeup()
    {
     
$this->o_XMLconfig = simplexml_load_string($this->s_XMLconfig);
    }
// __wakeup()
   
 
} // class myClass
?>
wouter at code-b dot nl
20.02.2007 11:08
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:

<?php
$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"
Kyle
10.12.2006 23:35
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.
Anonymous
7.04.2006 6:21
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.
fdouteaud at gmail dot com
9.03.2006 14:21
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.
info at evasion dot cc
6.02.2006 17:26
Sorry there's a mistake in the previous function :
<?php
  
function &getXMLnode($object, $param) {
       foreach(
$object as $key => $value) {
           if(isset(
$object->$key->$param)) {
               return
$object->$key->$param;
           }
           if(
is_object($object->$key)&&!empty($object->$key)) {
              
$new_obj = $object->$key;
              
// Must use getXMLnode function there (recursive)
              
$ret = getXMLnode($new_obj, $param);  

           }
       }
       if(
$ret) return (string) $ret;
       return
false;
   }
?>
skutter at imprecision dot net
3.02.2006 18:11
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);
?>
info at evasion dot cc
3.02.2006 12:37
Suppose you have loaded a XML file into $simpleXML_obj.
The structure is like below :

SimpleXMLElement Object
(

    [node1] => SimpleXMLElement Object
        (
            [subnode1] => value1
            [subnode2] => value2
            [subnode3] => value3
        )

    [node2] => SimpleXMLElement Object
        (
            [subnode4] => value4
            [subnode5] => value5
            [subnode6] => value6
        )

)

When searching a specific node in the object, you may use this function :
       
<?php

   
function &getXMLnode($object, $param) {
        foreach(
$object as $key => $value) {
            if(isset(
$object->$key->$param)) {
                return
$object->$key->$param;
            }
            if(
is_object($object->$key)&&!empty($object->$key)) {
               
$new_obj = $object->$key;
               
$ret = getCfgParam($new_obj, $param);   
            }
        }
        if(
$ret) return (string) $ret;
        return
false;
    }
?>

So if you want to get subnode4 value you may use this function like this :

<?php
$result
= getXMLnode($simpleXML_obj, 'subnode4');
echo
$result;
?>

It display "value4"
patrick at procurios dot nl
12.01.2006 15:46
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".
genialbrainmachine at NOSPAM dot tiscali dot it
30.09.2005 17:52
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
mark
12.09.2005 20:06
If the property of an object is empty the array is not created. Here is a version object2array that transfers properly.

<?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] = ($key && !$value) ? NULL : object2array($value);
        }
        else return
$object;
    }

    return
$return;
}
?>



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)