|
|
 |
XCVIII. SimpleXML functionsIntroduzione| Attenzione | Questo modulo è
SPERIMENTALE. Ovvero, il comportamento di queste
funzioni, i nomi di queste funzioni, in definitiva tutto ciò
che è documentato qui può cambiare nei futuri rilasci
del PHP senza preavviso. Siete avvisati, l'uso di questo modulo
è a vostro rischio. |
The SimpleXML extension provides a very simple and easily usable
toolset to convert XML to an object that can be processed with
normal property selectors and array iterators.
Installazione
This extension is only available if PHP was configured with
--enable-simplexml. The
PHP configuration script does this by default.
Esempi
Many examples in this reference require an XML string. Instead of
repeating this string in every example, we put it into a file which
we include in each example. This included file is shown in the
following example section. Alternatively, you could create an XML
document and read it with simplexml_load_file().
Esempio 1. Include file example.php with XML string |
<?php
$xmlstr = <<<XML
<?xml version='1.0' standalone='yes'?>
<movies>
<movie>
<title>PHP: Behind the Parser</title>
<characters>
<character>
<name>Ms. Coder</name>
<actor>Onlivia Actora</actor>
</character>
<character>
<name>Mr. Coder</name>
<actor>El ActÓr</actor>
</character>
</characters>
<plot>
So, this language. It's like, a programming language. Or is it a
scripting language? All is revealed in this thrilling horror spoof
of a documentary.
</plot>
<rating type="thumbs">7</rating>
<rating type="stars">5</rating>
</movie>
</movies>
XML;
?>
|
|
The simplicity of SimpleXML appears most clearly when one extracts
a string or number from a basic XML document.
Esempio 2. Getting <plot> |
<?php
include 'example.php';
$xml = simplexml_load_string($xmlstr);
echo $xml->movie[0]->plot; ?>
|
|
Esempio 3. Accessing non-unique elements in SimpleXML
When multiple instances of an element exist as children of
a single parent element, normal iteration techniques apply.
|
<?php
include 'example.php';
$xml = simplexml_load_string($xmlstr);
foreach ($xml->movie as $movie) {
echo $movie->plot, '<br />';
}
?>
|
|
Esempio 4. Using attributes
So far, we have only covered the work of reading element names
and their values. SimpleXML can also access element attributes.
Access attributes of an element just as you would elements
of an array.
|
<?php
include 'example.php';
$xml = simplexml_load_string($xmlstr);
foreach ($xml->movie[0]->rating as $rating) {
switch((string) $rating['type']) { case 'thumbs':
echo $rating, ' thumbs up';
break;
case 'stars':
echo $rating, ' stars';
break;
}
}
?>
|
|
Esempio 5. Comparing Elements and Attributes with Text
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.
|
<?php
include 'example.php';
$xml = simplexml_load_string($xmlstr);
if ((string) $xml->movie->title == 'PHP: Behind the Parser') {
print 'My favorite movie.';
}
htmlentities((string) $xml->movie->title);
?>
|
|
Esempio 6. Using Xpath
SimpleXML includes builtin Xpath support.
To find all <character> elements:
|
<?php
include 'example.php';
$xml = simplexml_load_string($xmlstr);
foreach ($xml->xpath('//character') as $character) {
echo $character->name, 'played by ', $character->actor, '<br />';
}
?>
|
'//' serves as a wildcard. To specify absolute
paths, omit one of the slashes.
|
Esempio 7. Setting values
Data in SimpleXML doesn't have to be constant. The object allows
for manipulation of all of its elements.
|
<?php
include 'example.php';
$xml = simplexml_load_string($xmlstr);
$xml->movie[0]->actor[0]->age = '21';
echo $xml->asXML();
?>
|
The above code will output a new XML document, just like the original,
except that the new XML will define Ms. Coder's age as 21.
|
Esempio 8. DOM Interoperability
PHP has a mechanism to convert XML nodes between SimpleXML
and DOM formats. This example shows how one might change
a DOM element to SimpleXML.
|
<?php
$dom = new domDocument;
$dom->loadXML('<books><book><title>blah</title></book></books>');
if (!$dom) {
echo 'Error while parsing the document';
exit;
}
$s = simplexml_import_dom($dom);
echo $s->book[0]->title;
?>
|
|
add a note
User Contributed Notes
SimpleXML functions
tk AT bytecrash DOT net
30-Apr-2004 02:41
As of PHP5 RC2 the simplexml_element class was renamed to SimpleXMLElement without mentioning it in the changelog or updateing the docs. So don't get confused when you get a fatal error that there is no simplexml_element class when you had used it with things like typehinting or instanceOf. Just update your sources to the new classname and things should work fine again. ;-)
Cheers, Thorsten
manicdepressive at mindless dot com
24-Apr-2004 12:13
I had to make adjustments to get the above 'Setting Values' example to work on WindowsXP with PHP5rc4: I changed the 'path' to follow more accurately the structure of the document, which it does not appear to do in the example. Also, thus far with my installation it appears that you can only set values of preexisting nodes ('name'), and not add a new node ('age').
<?php
$xml->movie[0]->actor[0]->age = '21'; $xml->movie[0]->characters[0]->character[0]->age = '21' ; $xml->movie[0]->characters[0]->character[0]->name = 'BEAVIS'; ?>
code till dawn! mark meves!
Christophe VG
22-Apr-2004 06:34
In reply to : ash at bigfoot dot de
The simpleXMLtoArray function you propose is actually the same as doing:
<?php
include 'example.php';
$xml = simplexml_load_string($xmlstr);
$ar = (array) $xml;
?>
It has besides that one little problem. It drops the attribute information.
The following function also takes in account the attributes. It treats them as if they where children.
<?php
function &simplexml_to_array( $xml ) {
$ar = array();
foreach( $xml->children() as $k => $v ) {
$child = simplexml_to_array( $v );
if( count($child) == 0 ) {
$child = (string)$v;
}
foreach( $v->attributes() as $ak => $av ) {
if( !is_array( $child ) ) {
$child = array( "value" => $child );
}
$child[$ak] = (string)$av;
}
if( !in_array( $k, array_keys($ar) ) ) {
$ar[$k] = $child;
} else {
$ar[$k] = array( $ar[$k] );
$ar[$k][] = $child;
}
}
return $ar;
}
include 'example.php';
$xml = simplexml_load_string($xmlstr);
print_r( simplexml_to_array( $xml ) );
?>
The resulting array looks like this :
Array
(
[movie] => Array
(
[title] => PHP: Behind the Parser
[characters] => Array
(
[character] => Array
(
[0] => Array
(
[name] => Ms. Coder
[actor] => Onlivia Actora
)
[1] => Array
(
[name] => Mr. Coder
[actor] => El ActÓr
)
)
)
[plot] =>
So, this language. It's like, a programming language. Or is it a
scripting language? All is revealed in this thrilling horror spoof
of a documentary.
[rating] => Array
(
[0] => Array
(
[value] => 7
[type] => thumbs
)
[1] => Array
(
[value] => 5
[type] => stars
)
)
)
)
I hope this can help someone. I needed this because you cannot put a simpleXML object into eg. a session due to serialization issues. This way I can store the information inside the XML document, eg. in a session, eliminating the need to reparse it time after time while still having a rather nice interface for accessing the data.
cvladan at list dot co dot yu
12-Mar-2004 05:05
I had a problem detecting the existance of a node, in SimpleXML. Meaning, if exists, even if empty.
I solved this stupid problem by using this function:
function node_exist($objSXml)
{
$objTemp = (object) $objSXml;
return ($objTemp->scalar != null);
}
It would be nice to have something more logical, as SimpleXML function. Or, when you cast to (bool), to evaluate to node existance.
ash at bigfoot dot de
01-Mar-2004 01:20
I had problems to use SimpleXML with OpenOffice's content.xml.
Although
print_r($simple_xml);
printed the whole XML object
simplexml_element Object
(
[script] => simplexml_element Object
(
)
[font-decls] => simplexml_element Object
(
[font-decl] => Array
...
all first level object vars (script, font-decls, automatic-styles, body) contained nothing if I tried to access them:
print_r($simple_xml->{'font-decls'});
returned
simplexml_element Object
(
)
and direct access to a deeper value returns NULL:
echo(gettype($simple_xml->{'font-decls'}->{'font-decl'}));
So I wrote a function to turn the whole object into an array, maybe you find it useful.
function &simpleXMLtoArray(&$simple_xml) {
$xml_array = (array)$simple_xml;
$result = array();
foreach ($xml_array as $key => $value) {
if(is_object($value) || is_array($value))
$result[$key]=&simpleXMLtoArray($value);
else
$result[$key]=$value;
}
return $result;
}
print_r(simpleXMLtoArray($simple_xml));
jwhite at theideabasket dot com
21-Feb-2004 10:31
One very important thing that I've found out (after much fiddling around) is that you have to typecast a SimpleXML variable to a string before assigning it to another variable. For example, if you wanted to add a certain attribute of several XML tags to an array using each tag's contents as the index, you'd have to do this:
<?php
foreach ($xml->paragraph as $i => $prop) {
$propArray[(string)$prop] = (string)$prop['someattribute'];
}
?>
I guess this makes sense when you read about how the __toString() method works in the Zend Engine 2.0 change notes (http://www.php.net/zend-engine-2.php), but it seems just a wee bit complicated syntactically to me.
greg dot steffensen at spamless dot richmond dot edu
19-Feb-2004 09:04
Simplexml's simplicity can be deceptive. Simplexml elements behave either as objects or strings, depending on the context in which they're used (through overloading of the __toString() method, I assume). Statements implying conversion to string treat them as strings, while assignment operations treat them as objects. This can lead to unexpected behavior if, for example, you are trying to compare the values of two Simplexml elements. The expected syntax will not work. To force conversion to strings, just place whatever Simplexml element you're using inside double quotes. For example:
$s = simplexml_load_string('<foo>43</foo> <bar>43</bar>');
// Evaluates to false
($s->foo == $s->bar);
// Evaluates to true
("$s->foo" == "$s->bar");
This is accurate as of PHP 5 Beta 4.
| |