总有人间一两风,填我十万八千梦

PHP simplexml_load_string 用法 手册 | 示例代码

PHP开发手册 归档 389℃ 0评论

simplexml_load_string

(PHP 5, PHP 7)

simplexml_load_string Interprets a string of XML into an object

说明

simplexml_load_string ( string $data [, string $class_name = "SimpleXMLElement" [, int $options = 0 [, string $ns = "" [, bool $is_prefix = FALSE ]]]] ) : SimpleXMLElement

Takes a well-formed XML string and returns it as an object.

参数

data

A well-formed XML string

class_name

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.

options

Since PHP 5.1.0 and Libxml 2.6.0, you may also use the options parameter to specify additional Libxml parameters.

ns

Namespace prefix or URI.

is_prefix

TRUE if ns is a prefix, FALSE if it's a URI; defaults to FALSE.

返回值

Returns an object of class SimpleXMLElement with properties containing the data held within the xml document, 或者在失败时返回 FALSE.

Warning

此函数可能返回布尔值 FALSE,但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

错误/异常

Produces an E_WARNING error message for each error found in the XML data.

Tip

Use libxml_use_internal_errors() to suppress all XML errors, and libxml_get_errors() to iterate over them afterwards.

范例

Example #1 Interpret an XML string

<?php
$string 
= <<<XML
<?xml version='1.0'?> 
<document>
 <title>Forty What?</title>
 <from>Joe</from>
 <to>Jane</to>
 <body>
  I know that's the answer -- but what's the question?
 </body>
</document>
XML;

$xml simplexml_load_string($string);

print_r($xml);
?>

以上例程会输出:

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.

参见

用户贡献的笔记

ascammon at hotmail dot com

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:

<?php
$xml
= simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA LIBXML_NOBLANKS);
?>

Diego Araos, diego at klapmedia dot com

A simpler way to transform the result into an array (requires json module).

<?php
function object2array($object) { return @json_decode(@json_encode($object),1); }
?>

Example:
<?php
$xml_object
=simplexml_load_string('<SOME XML DATA');
$xml_array=object2array($xml_object);
?>

rowan dot collins at gmail dot com

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

The key is noted above example #6 here:
http://uk2.php.net/manual/en/simplexml.examples.php

"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.

<?php
$xml
= simplexml_load_string('<foo>Text1 &amp; XML entities</foo>');
print_r($xml);
/*
SimpleXMLElement Object
(
    [0] => Text1 & XML entities
)
*/

$xml2 = simplexml_load_string('<foo><![CDATA[Text2 & raw data]]></foo>');
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
?>

javalc6 at gmail dot com

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.

<?php
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();
?>

meustrus

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.

<?php

$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<ns1:Root xmlns:ns1="http://example.com/custom">
<ns1:Node>There's stuff here</ns1:Node>
</ns1:Root>
XML;

$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;

?>

See:

https://bugs.php.net/bug.php?id=31045
https://bugs.php.net/bug.php?id=30972
https://bugs.php.net/bug.php?id=69596

Pedro

Attention:

simplexml_load_string has a problem with entities other than (&lt;, &gt;, &amp;, &quot; and &apos;).

Use numeric character references instead!

mindpower

A simple extension that adds a method for retrieving a specific attribute:

<?php
class simple_xml_extended extends SimpleXMLElement
{
    public    function   
Attribute($name)
    {
        foreach(
$this->Attributes() as $key=>$val)
        {
            if(
$key == $name)
                return (string)
$val;
        }
    }

}

$xml = simplexml_load_string('
<xml>
  <dog type="poodle" owner="Mrs Smith">Rover</dog>
</xml>'
, 'simple_xml_extended');

echo $xml->dog->Attribute('type');

?>

outputs 'poodle'

I prefer to use this technique rather than typecasting attributes.

bojan

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:

<?php

// data in xml
$xml_txt = '
<root>
  <folder ID="65" active="1" permission="1"><![CDATA[aaaa]]></folder>
  <folder ID="65" active="1" permission="1"><![CDATA[bbbb]]></folder>
</root>'
;

// 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
        )

    [0] => aaaa
)

SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [ID] => 65
            [active] => 1
            [permission] => 1
        )

    [0] => bbbb
)

*/
?>

jeff at creabilis dot com

If you want to set the charset of the outputed xml, simply set the encoding attribute like this :

<?php simplexml_load_string('<?xml version="1.0" encoding="utf-8"?><xml/>'); ?>

The generated xml outputed by $xml->asXML will containt accentuated characters like 'é' instead of &#xE9;.

Hope this help

Julio Cesar Oliveira

The XML2Array func now Recursive!

<?php
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 ;
}
?>

Anonymous

Use libxml_disable_entity_loader() to restrict loading of external files.  See http://www.idontplaydarts.com/2011/02/scanning-the-internal-network-using-simplexml/

erguven dot m at gmail dot com

if you want to use a class which exists in a name space, use it full name. simple_load_string did not recognize short one.

class.new.php
<?php
namespace foobar;

class new extends SimpleXMLElement
{
    public function do()
    {
        echo
"done";
    }
}
?>

false.php
<?php
use foobarnew;

$result = simplexml_load_string($xml, 'new'); // it gives warning
$result->do(); // fatal error
?>

true.php
<?php
use foobarnew;
$result = simplexml_load_string($xml, 'foobarnew');

$result->do(); // prints done
?>

Bob

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).
<?php
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;
}
?>

amir_abiri at ipcmedia dot com

It doesn't seem to be documented anywhere, but you can refer to an element "value" for the purpose of changing it like so:

<?php
$xml
= simplexml_load_string('<root><number>1</number></root>');
echo
$xml->asXml(). "nn";

$xml->number->{0} = $xml->number->{0} + 1;

echo $xml->asXml();
?>

echos:
<?xml version="1.0"?>
<root><number>1</number></root>

<?xml version="1.0"?>
<root><number>2</number></root>

However, this only works with a direct assignment, not with any of the other operators:

<?php
$xml
= simplexml_load_string('<root><number>1</number></root>');
echo
$xml->asXml(). "nn";

$xml->number->{0} += 1;
// Or:
$xml->number->{0}++;

echo $xml->asXml();
?>

Both of the above cases would result in:

<?xml version="1.0"?>
<root><number>1</number></root>

<?xml version="1.0"?>
<root><number>1<0/></number></root>

hattori at hanso dot com

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

<?PHP
if(strpos($content, '<![CDATA[')) {
   function
parseCDATA($data) {
      return
htmlentities($data[1]);
   }
  
$content = preg_replace_callback(
     
'#<![CDATA[(.*)]]>#',
     
'parseCDATA',
     
str_replace("n", " ", $content)
   );
}
?>

nbijnens at servs dot eu

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:

<?php
$xml
= new DOMDocument();
$xml->loadXML ($XMLString);
           
$xml->xinclude();
$xml = simplexml_import_dom($xml);

?>

m dot ament at mailcity dot com

Warning:

The parsing of XML-data will stop when reaching character 0.
Please avoid this character in your XML-data.

Maciek Ruckgaber <maciekrb at gmai dot com>

after wondering around some time, i just realized something (maybe obvious, not very much for me). Hope helps someone to not waste time as i did :-P

when you have something like:

<?php
$xmlstr
= <<<XML
<?xml version="1.0" encoding="utf-8"?>
<double xmlns="http://foosite.foo/">2328</double>
XML;
?>

you will have the simpleXML object "transformed" to the text() content:

<?php
$xml
= simplexml_load_string($xmlstr);
echo
$xml; // this will echo 2328  (string)
?>

cellog at php dot net

simplexml does not simply handle CDATA sections in a foreach loop.

<?php
$sx
= simplexml_load_string('
<test>
<one>hi</one>
<two><![CDATA[stuff]]></two>
<t>
  <for>two</for>
</t>
<multi>one</multi>
<multi>two</multi>
</test>'
);
foreach((array)
$sx as $tagname => $val) {
    if (
is_string($val)) {
      
// <one> will go here
   
} elseif (is_array($val)) {
      
// <multi> will go here because it happens multiple times
   
} elseif (is_object($val)) {
     
// <t> will go here because it contains tags
      // <two> will go here because it contains CDATA!
   
}
}
?>

To test in the loop, do this

<?php
if (count((array) $val) == 0) {
   
// this is not a tag that contains other tags
   
$val = '' . $val;
   
// now the CDATA is revealed magically.
}
?>

AllenJB

<?php
$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.

artistan at gmail dot com

Here is my update to Bob's simple SimpleXML wrapper function.
I noticed his version would turn an empty SimpleXMLElement into an empty array.

<?php
   
/**
     * 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;
    }
?>

转载请注明:悠然品鉴 » PHP simplexml_load_string 用法 手册 | 示例代码

喜欢 (0)or分享 (0)
发表我的评论
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址