SimpleXML

Коментарии

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.
2008-06-30 09:58:55
http://php5.kiev.ua/manual/ru/book.simplexml.html
Автор:
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;
2008-11-18 16:27:21
http://php5.kiev.ua/manual/ru/book.simplexml.html
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]
?>
2009-01-25 05:05:10
http://php5.kiev.ua/manual/ru/book.simplexml.html
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;
?>
2009-04-28 03:37:29
http://php5.kiev.ua/manual/ru/book.simplexml.html
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 
?>
2010-01-20 14:58:40
http://php5.kiev.ua/manual/ru/book.simplexml.html
Автор:
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.]
2010-02-17 12:21:24
http://php5.kiev.ua/manual/ru/book.simplexml.html
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.
2010-11-18 07:14:40
http://php5.kiev.ua/manual/ru/book.simplexml.html
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) == ){
       
$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.
2010-11-23 19:33:51
http://php5.kiev.ua/manual/ru/book.simplexml.html
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();
}
?>
2011-01-19 13:37:11
http://php5.kiev.ua/manual/ru/book.simplexml.html
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();
}
?>
2011-05-04 23:49:20
http://php5.kiev.ua/manual/ru/book.simplexml.html
Three line xml2array:

<?php

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

?>

Ta da!
2011-08-09 20:06:55
http://php5.kiev.ua/manual/ru/book.simplexml.html
Here is a recursive function that will convert a given SimpleXMLElement object into an array, preserving namespaces and attributes.

<?php
function xmlObjToArr($obj) {
       
$namespace $obj->getDocNamespaces(true);
       
$namespace[NULL] = NULL;
       
       
$children = array();
       
$attributes = array();
       
$name strtolower((string)$obj->getName());
       
       
$text trim((string)$obj);
        if( 
strlen($text) <= ) {
           
$text NULL;
        }
       
       
// get info for all namespaces
       
if(is_object($obj)) {
            foreach( 
$namespace as $ns=>$nsUrl ) {
               
// atributes
               
$objAttributes $obj->attributes($nstrue);
                foreach( 
$objAttributes as $attributeName => $attributeValue ) {
                   
$attribName strtolower(trim((string)$attributeName));
                   
$attribVal trim((string)$attributeValue);
                    if (!empty(
$ns)) {
                       
$attribName $ns ':' $attribName;
                    }
                   
$attributes[$attribName] = $attribVal;
                }
               
               
// children
               
$objChildren $obj->children($nstrue);
                foreach( 
$objChildren as $childName=>$child ) {
                   
$childName strtolower((string)$childName);
                    if( !empty(
$ns) ) {
                       
$childName $ns.':'.$childName;
                    }
                   
$children[$childName][] = xmlObjToArr($child);
                }
            }
        }
       
        return array(
           
'name'=>$name,
           
'text'=>$text,
           
'attributes'=>$attributes,
           
'children'=>$children
       
);
    }
?>
2012-05-17 22:00:19
http://php5.kiev.ua/manual/ru/book.simplexml.html
Автор:
Simple means simple.  If you know the structure and just want the value of a tag:

<?php
$xml 
simplexml_load_file($xmlfile);
print 
$xml->City->Street->Address->HouseColor;
?>

Warning, numbers can come out as strings, empty elements like <HouseColor></HouseColor> come out as array(0)
2012-12-28 23:55:18
http://php5.kiev.ua/manual/ru/book.simplexml.html
Wrapper XMLReader class, for simple SAX-reading huge xml:
https://github.com/dkrnl/SimpleXMLReader

Usage example: http://github.com/dkrnl/SimpleXMLReader/blob/master/examples/example1.php

<?php

/**
 * Simple XML Reader
 *
 * @license Public Domain
 * @author Dmitry Pyatkov(aka dkrnl) <dkrnl@yandex.ru>
 * @url http://github.com/dkrnl/SimpleXMLReader
 */
class SimpleXMLReader extends XMLReader
{

   
/**
     * Callbacks
     *
     * @var array
     */
   
protected $callback = array();

   
/**
     * Add node callback
     *
     * @param  string   $name
     * @param  callback $callback
     * @param  integer  $nodeType
     * @return SimpleXMLReader
     */
   
public function registerCallback($name$callback$nodeType XMLREADER::ELEMENT)
    {
        if (isset(
$this->callback[$nodeType][$name])) {
            throw new 
Exception("Already exists callback $name($nodeType).");
        }
        if (!
is_callable($callback)) {
            throw new 
Exception("Already exists parser callback $name($nodeType).");
        }
       
$this->callback[$nodeType][$name] = $callback;
        return 
$this;
    }

   
/**
     * Remove node callback
     *
     * @param  string  $name
     * @param  integer $nodeType
     * @return SimpleXMLReader
     */
   
public function unRegisterCallback($name$nodeType XMLREADER::ELEMENT)
    {
        if (!isset(
$this->callback[$nodeType][$name])) {
            throw new 
Exception("Unknow parser callback $name($nodeType).");
        }
        unset(
$this->callback[$nodeType][$name]);
        return 
$this;
    }

   
/**
     * Run parser
     *
     * @return void
     */
   
public function parse()
    {
        if (empty(
$this->callback)) {
            throw new 
Exception("Empty parser callback.");
        }
       
$continue true;
        while (
$continue && $this->read()) {
            if (isset(
$this->callback[$this->nodeType][$this->name])) {
               
$continue call_user_func($this->callback[$this->nodeType][$this->name], $this);
            }
        }
    }

   
/**
     * Run XPath query on current node
     *
     * @param  string $path
     * @param  string $version
     * @param  string $encoding
     * @return array(SimpleXMLElement)
     */
   
public function expandXpath($path$version "1.0"$encoding "UTF-8")
    {
        return 
$this->expandSimpleXml($version$encoding)->xpath($path);
    }

   
/**
     * Expand current node to string
     *
     * @param  string $version
     * @param  string $encoding
     * @return SimpleXMLElement
     */
   
public function expandString($version "1.0"$encoding "UTF-8")
    {
        return 
$this->expandSimpleXml($version$encoding)->asXML();
    }

   
/**
     * Expand current node to SimpleXMLElement
     *
     * @param  string $version
     * @param  string $encoding
     * @param  string $className
     * @return SimpleXMLElement
     */
   
public function expandSimpleXml($version "1.0"$encoding "UTF-8"$className null)
    {
       
$element $this->expand();
       
$document = new DomDocument($version$encoding);
       
$node $document->importNode($elementtrue);
       
$document->appendChild($node);
        return 
simplexml_import_dom($node$className);
    }

   
/**
     * Expand current node to DomDocument
     *
     * @param  string $version
     * @param  string $encoding
     * @return DomDocument
     */
   
public function expandDomDocument($version "1.0"$encoding "UTF-8")
    {
       
$element $this->expand();
       
$document = new DomDocument($version$encoding);
       
$node $document->importNode($elementtrue);
       
$document->appendChild($node);
        return 
$document;
    }

}
?>
2013-09-30 05:57:35
http://php5.kiev.ua/manual/ru/book.simplexml.html
Two lines xml2array:

<?php

$xml 
simplexml_load_string($xmlstring);
$array = (array) $xml;

?>
2016-03-30 12:57:23
http://php5.kiev.ua/manual/ru/book.simplexml.html

    Поддержать сайт на родительском проекте КГБ