SimpleXML Functions

Table of Contents

add a note

User Contributed Notes 37 notes

up
8
cmsa at gmx dot de
16 years ago
I had a problem with entities.

My first solution:
I saved Data that way:
$ENTRY_->
addchild('Nachricht',htmlentities($_POST["blog"]));

Had Entities in the XML-File like:
<!ENTITY auml "&amp;auml">

And I loaded the Data that way:
html_entity_decode($ENTRY->Nachname);

But after saving and
loading the xml-file the entity-entry
<!ENTITY auml "&amp;auml">
disappeared. strange...

My second solution:
With saving the Data this way:
$ENTRY_->
addchild('Nachricht',htmlentities(htmlentities($_POST["blog"])));

I can now load it with html_entity_decode without the
entity-entry in the XML-file!
I tested it with äöü.

Hope it helpes.
up
4
brcavanagh AT NO SPAM hotmail.com
18 years ago
If you are looking to use SimpleXML for anything but reading XML documents, you should really reconsider, and use the XML DOM library. By the time you get enough utilities implemented in DOM to handle all the set backs in SimpleXML, you will have defeated the purpose of using SimpleXML. There are a few reasons for this, and there are already many workrounds, but the primairy issues are this

1) No complex node assignment. You cannot switch nodes or replace them.

2) No appending new child nodes

3) Whenever you do something like $new_node = $xml_doc->node you will always get a reference even if you use a clone method, which will crash the script.

Other than that, its a great tool for reading docs.
up
15
help :-) @ theapotek :-) com
12 years ago
If you are having trouble accessing CDATA in your simplexml document, you don't need to str_replace/preg_replace the CDATA out before loading it with simplexml.

You can do this instead, and all your CDATA contents will be merged into the element contents as strings.

$xml = simplexml_load_file($xmlfile,
'SimpleXMLElement', LIBXML_NOCDATA);
up
6
r dot m dot 0100101 at gmail dot com
10 years ago
This is a slight adjustment to http://www.php.net/manual/en/ref.simplexml.php#103617 's function.
The function given by them would convert a simpleXML to an array but only at the highest level. Once you add the is_array check with the is_object it should convert each level to an array (well it did for me through 3 levels).

function simpleXmlObjectToArray ( $xmlObject, $out = array () )
{
foreach ( (array) $xmlObject as $index => $node )
$out[$index] = ( is_object ( $node ) || is_array($node) )
? simpleXmlObjectToArray ( $node )
: $node;

return $out;
}
Happy Coding!
up
5
brandonkirsch at gmail dot com
10 years ago
Contrary to other notes posted here, SimpleXML *DOES NOT* properly handle non-UTF8 encoded XML documents.

A proper "iso-8859-1" declared and encoded XML document will not parse with SimpleXML for PHP 5.2.17 or 5.5.1 when using extended characters (that is, byte values greater than 127)

DOMDocument, on the other hand, will correctly parse incoming iso-8859-1 XML documents and can also be used to perform character translation to UTF8:

$dom = new DOMDocument();

if($dom->loadXML($fileContents)){ // $fileContents is an XML document with iso-8859-1 encoding specified in the declaration
$dom->encoding = 'utf-8'; // convert document encoding to UTF8
return $dom->saveXML(); // return valid, utf8-encoded XML
up
5
T CHASSAGNETTE t_chassagnette at yahoo dot fr
18 years ago
Another method to parse an XML Document into a PHP array with SIMPLEXML inspired from Daniel FAIVRE !

<?php
function xml2php($xml)
{
$fils = 0;
$tab = false;
$array = array();
foreach(
$xml->children() as $key => $value)
{
$child = xml2php($value);

//To deal with the attributes
foreach($node->attributes() as $ak=>$av)
{
$child[$ak] = (string)$av;

}

//Let see if the new child is not in the array
if($tab==false && in_array($key,array_keys($array)))
{
//If this element is already in the array we will create an indexed array
$tmp = $array[$key];
$array[$key] = NULL;
$array[$key][] = $tmp;
$array[$key][] = $child;
$tab = true;
}
elseif(
$tab == true)
{
//Add an element in an existing array
$array[$key][] = $child;
}
else
{
//Add a simple element
$array[$key] = $child;
}

$fils++;
}


if(
$fils==0)
{
return (string)
$xml;
}

return
$array;

}
?>
up
4
joel [from the website] purerave.com
16 years ago
It doesn't mention this anywhere, but creationg a new SimpleXMLElement object from a non-valid string throws an exception. It looks ugly in the php log as it dumps the stack in multiple lines.

The correct way to create a new SimpleXMLElement object is like so:
<?php
$xmlstr
= ''; // empty to throw an exception
try {
$xml = new SimpleXMLElement($xmlstr);
} catch (
Exception $e) {
// handle the error
echo '$xmlstr is not a valid xml string';
}
?>
up
4
paul at preinheimer dot com
18 years ago
Hi,

If you want to access an element that has a dash in its name, (as is common with the XML documents provided by the Library of Congress, as well as the NWS) you will need to handle it a little bit differently.

You can either use XPATH, which works fine, but will return an array of results every time, even if there is a single result.
eg.

<?php
$xml
->xpath('/data/time-layout/start-valid-time');
?>

You can also choose just to encapsulate the element names containing a dash:
<?php $xml->data->{'time-layout'}->{'start-valid-time'} ?>

--

On a only partially related note, dealing with SimpleXML is one of the only times I have employed casting with PHP. While iterating (foreach) through the valid times, echo'ing the element worked great (it merely echo'ed the apropriate time), assigning it to another variable resulted in a SimpleXML object containing the time to be assigned, rather than just the time itself. This was resolved by casting the time to a string:

<?php
foreach($xml->data->{'time-layout'}->{'start-valid-time'} AS $time)
{
$weatherDates[] = (string) $time;
}
?>
up
4
nelson_menezes at yahoo dot co dot uk
18 years ago
Note that SimpleXML expects to both read and output XML in UTF-8 encoding. You'll need to add a line such as this at the top of your input XML file if it isn't saved in UTF-8 (adjust to whatever encoding used):

<?xml version="1.0" encoding="ISO-8859-1" ?>

On the output side of things, if you're not serving/handling UTF-8, you'll need to use utf8_decode() [red. but that will only work for ISO-8859-1, not other encodings]. Common mistake: http://bugs.php.net/bug.php?id=28154
up
6
William Fahria
10 years ago
A simple implementation:
You can inform a direct XML in text format to the function.

function eoXML2Array($xmlContent, $out = array()){
$xmlObject = is_object($xmlContent) ? $xmlContent : simplexml_load_string($xmlContent);
foreach((array) $xmlObject as $index => $node)
$out[$index] = ( is_object($node) || is_array($node) ) ? eoXML2Array( $node ) : $node;
return $out;
}

Usage: $your_array = eoXML2Array(your xml text);
up
3
Douglas Marsh
14 years ago
SimpleXML is really nice for loading/converting XML data into native PHP data structures. I was considering crude searching of SVG for the width/height and since it really is an XML file... I found a SUPER easy method for parsing out the information I wanted:

<?php
// putting incomplete SVG data inline for readability
$RawXML = <<< XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://www.example.com/dc"
xmlns:cc="http://www.example.com/cc"
xmlns:rdf="http://www.example.com/rdf"
xmlns:svg="http://www.example.com/svg"
xmlns="http://www.example.com/"
xmlns:sodipodi="http://www.example.com/sodipodi"
xmlns:inkscape="http://www.example.com/inkscape"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
width="586.25"
height="743.75"
xml:space="preserve"
sodipodi:docname="some_svg_file.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<!-- portions removed to keep this short -->
</svg>
XML;

$svg = new SimpleXMLElement($RawXML);

$height = $svg['height'];
$width = $svg['width'];

echo
"The width x height is: ${width} x ${height} \n";

?>
up
6
andrvm
15 years ago
<?php
/**
* Remove node/nodes xml with xpath
*
* @param SimpleXMLElement $xml
* @param string XPath $path
* @param string ('one'|'child'|'all') $multi
*
* Use:
*
* Example xml file - http://ru2.php.net/manual/ru/ref.simplexml.php
*
* $xml = simplexml_load_file($xmlfile);
*
* //1. remove only 1 node (without child nodes)
* // $path must return only 1 (unique) node without child nodes
* removeNode($xml, '//movie/rating[@type="thumbs"]');
*
* //2. remove 1 node (with 1 child nodes)
* // $path can return any nodes - will be removed only first node
* // with all child nodes
* removeNode($xml, '//characters', 'child')
*
* //3. remove all nodes (with child nodes)
* // $path can return any nodes - will be removed all
* // with child nodes
* removeNode($xml, '//rating', 'all')
*
* $xml->asXML($xmlfile);
*
*/
function removeNode($xml, $path, $multi='one')
{
$result = $xml->xpath($path);

# for wrong $path
if (!isset($result[0])) return false;

switch (
$multi) {
case
'all':
$errlevel = error_reporting(E_ALL & ~E_WARNING);
foreach (
$result as $r) unset ($r[0]);
error_reporting