Movatterモバイル変換


[0]ホーム

URL:


PHP 8.5.0 RC4 available for testing
    Introduction »
    « libxml_use_internal_errors

    SimpleXML

    Found A Problem?

    Learn How To Improve This PageSubmit a Pull RequestReport a Bug
    add a note

    User Contributed Notes15 notes

    288
    soloman at textgrid dot com
    14 years ago
    Three line xml2array:

    <?php

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

    ?>

    Ta da!
    QLeap
    16 years ago
    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;
    oscargodson at gmail dot com
    16 years ago
    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]
    ?>
    xaviered at gmail dot com
    13 years ago
    Here is a recursive function that will convert a given SimpleXMLElement object into an array, preserving namespaces and attributes.

    <?php
    functionxmlObjToArr($obj) {
    $namespace=$obj->getDocNamespaces(true);
    $namespace[NULL] =NULL;

    $children= array();
    $attributes= array();
    $name=strtolower((string)$obj->getName());

    $text=trim((string)$obj);
    if(
    strlen($text) <=0) {
    $text=NULL;
    }

    // get info for all namespaces
    if(is_object($obj)) {
    foreach(
    $namespaceas$ns=>$nsUrl) {
    // atributes
    $objAttributes=$obj->attributes($ns,true);
    foreach(
    $objAttributesas$attributeName=>$attributeValue) {
    $attribName=strtolower(trim((string)$attributeName));
    $attribVal=trim((string)$attributeValue);
    if (!empty(
    $ns)) {
    $attribName=$ns.':'.$attribName;
    }
    $attributes[$attribName] =$attribVal;
    }

    // children
    $objChildren=$obj->children($ns,true);
    foreach(
    $objChildrenas$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
    );
    }
    ?>
    aalaap at gmail dot com
    17 years ago
    Here are two quick and dirty functions that use SimpleXML to detect if a feed xml is RSS or ATOM:

    <?php
    functionis_rss($feedxml) {
    @
    $feed= newSimpleXMLElement($feedxml);

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

    function
    is_atom($feedxml) {
    @
    $feed= newSimpleXMLElement($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.
    whyme
    12 years ago
    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)
    mahmutta at gmail dot com
    15 years ago
    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
    ?>
    dkrnl at yandex dot ru
    12 years ago
    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>
    * @urlhttp://github.com/dkrnl/SimpleXMLReader
    */
    classSimpleXMLReaderextendsXMLReader
    {

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

    /**
    * Add node callback
    *
    * @param string $name
    * @param callback $callback
    * @param integer $nodeType
    * @return SimpleXMLReader
    */
    public functionregisterCallback($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 functionunRegisterCallback($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 functionparse()
    {
    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 functionexpandXpath($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 functionexpandString($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 functionexpandSimpleXml($version="1.0",$encoding="UTF-8",$className=null)
    {
    $element=$this->expand();
    $document= newDomDocument($version,$encoding);
    $node=$document->importNode($element,true);
    $document->appendChild($node);
    return
    simplexml_import_dom($node,$className);
    }

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

    }
    ?>
    streaver91 at gmail dot com
    14 years ago
    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
    functionarray2XML($arr,$root) {
    $xml= newSimpleXMLElement("<?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();
    }
    ?>
    philipp at strazny dot com
    14 years ago
    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
    functionXMLToArrayFlat($xml, &$return,$path='',$root=false)
    {
    $children= array();
    if (
    $xmlinstanceofSimpleXMLElement) {
    $children=$xml->children();
    if (
    $root){// we're at root
    $path.='/'.$xml->getName();
    }
    }
    if (
    count($children) ==0){
    $return[$path] = (string)$xml;
    return;
    }
    $seen=array();
    foreach (
    $childrenas$child=>$value) {
    $childname= ($childinstanceofSimpleXMLElement)?$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($filesas$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
    14 years ago
    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.
    phil at dier dot us
    14 years ago
    Here's a function I came up with to convert an associative array to XML. Works for multidimensional arrays as well.

    <?php
    functionassocArrayToXML($root_element_name,$ar)
    {
    $xml= newSimpleXMLElement("<?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();
    }
    ?>
    emmanuel
    15 years ago
    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
    functioncallMe($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.]
    oleg at mastak dot fi
    9 years ago
    Two lines xml2array:

    <?php

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

    ?>
    mail at kleineedv dot de
    16 years ago
    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;
    ?>
    add a note
    To Top
    and to navigate •Enter to select •Esc to close •/ to open
    PressEnter without selection to search using Google

    [8]ページ先頭

    ©2009-2025 Movatter.jp