152

I have used the XML Parser before, and even though it worked OK, I wasn't happy with it in general, it felt like I was using workarounds for things that should be basic functionality.

I recently saw SimpleXML but I haven't tried it yet. Is it any simpler? What advantages and disadvantages do both have? Any other parsers you've used?

Gras Double
  • 15,901
  • 8
  • 56
  • 54
Murat Ayfer
  • 3,894
  • 6
  • 29
  • 26
  • 4
    Suggestion for anyone reading this: ask a question describing what you need to *do* with the XML (beyond simply parsing it) and you'll probably get a much better answer. – Shog9 Mar 11 '13 at 23:39
  • 2
    Please see the following general reference question for the PHP tag: **[How to parse and process HTML/XML with PHP?](http://stackoverflow.com/questions/3577641/how-to-parse-and-process-html-xml-with-php)** – hakre Mar 20 '13 at 15:39

6 Answers6

110

I would have to say SimpleXML takes the cake because it is firstly an extension, written in C, and is very fast. But second, the parsed document takes the form of a PHP object. So you can "query" like $root->myElement.

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
Robert K
  • 30,064
  • 12
  • 61
  • 79
  • 14
    simplexml is the best. But is not that good working with namespaces, it can get tricky sometimes – pleasedontbelong Sep 01 '10 at 08:09
  • 2
    Yes I think it's best too. And I use xpath with it. $xml->xpath("//block");//THIS IS SUPER :) – Vahan Mar 22 '12 at 20:15
  • 5
    I dont think its best. It doesnt support xml version="1.1" and throws warning about this fact (my PHP version is 5.3.6). I know that you can disable warnings and it work fine, but I don't think it's a good solution. So imagine what will happen, if your API provider change xml document version from 1.0 to 1.1? Second think is what @Gordon pointed out. SimpleXML loads entire document to memory. It's good solution but certainly not best. – Karol Apr 12 '12 at 10:40
  • 9
    Dealing with namespaced XML with SimpleXML sucks. – Jake Wilson Oct 12 '12 at 19:53
  • 4
    SimpleXML creates different structure when some node has one child and different when it has more children. It makes me sick! – Adam Pietrasiak Feb 01 '15 at 09:15
  • Do not use SimpleXml if you might, at any point in the future, have to change the XML. I have seen the resulting code... it is not a pretty sight. – Bet Lamed Dec 14 '15 at 15:26
  • @BetLamed I agree nowadays, but if you've tried to write a parser with DOMDocument you'll be in for 10x the code and lots of complexity. – Robert K Dec 14 '15 at 20:52
  • @jake-wilson It's SimpleXML - the clue is in the name – jim smith Mar 13 '17 at 11:49
  • @BetLamed alternatives? – agoldev Sep 19 '19 at 13:19
  • @agoldev Sorry I don't remember, I wrote this 4 years ago. In the project I was on, I think I ended up using SimpleXML and coding around the issues, because changing it would have been too much work... – Bet Lamed Sep 20 '19 at 08:56
43

Have a look at PHP's available XML extensions.

The main difference between XML Parser and SimpleXML is that the latter is not a pull parser. SimpleXML is built on top of the DOM extensions and will load the entire XML file into memory. XML Parser like XMLReader will only load the current node into memory. You define handlers for specific nodes which will get triggered when the Parser encounters it. That is faster and saves on memory. You pay for that with not being able to use XPath.

Personally, I find SimpleXml quite limiting (hence simple) in what it offers over DOM. You can switch between DOM and SimpleXml easily though, but I usually dont bother and go the DOM route directly. DOM is an implementation of the W3C DOM API, so you might be familiar with it from other languages, for instance JavaScript.

Gordon
  • 312,688
  • 75
  • 539
  • 559
39

This is a useful function for quick and easy xml parsing when an extension is not available:

<?php
/**
 * Convert XML to an Array
 *
 * @param string  $XML
 * @return array
 */
function XMLtoArray($XML)
{
    $xml_parser = xml_parser_create();
    xml_parse_into_struct($xml_parser, $XML, $vals);
    xml_parser_free($xml_parser);
    // wyznaczamy tablice z powtarzajacymi sie tagami na tym samym poziomie
    $_tmp='';
    foreach ($vals as $xml_elem) {
        $x_tag=$xml_elem['tag'];
        $x_level=$xml_elem['level'];
        $x_type=$xml_elem['type'];
        if ($x_level!=1 && $x_type == 'close') {
            if (isset($multi_key[$x_tag][$x_level]))
                $multi_key[$x_tag][$x_level]=1;
            else
                $multi_key[$x_tag][$x_level]=0;
        }
        if ($x_level!=1 && $x_type == 'complete') {
            if ($_tmp==$x_tag)
                $multi_key[$x_tag][$x_level]=1;
            $_tmp=$x_tag;
        }
    }
    // jedziemy po tablicy
    foreach ($vals as $xml_elem) {
        $x_tag=$xml_elem['tag'];
        $x_level=$xml_elem['level'];
        $x_type=$xml_elem['type'];
        if ($x_type == 'open')
            $level[$x_level] = $x_tag;
        $start_level = 1;
        $php_stmt = '$xml_array';
        if ($x_type=='close' && $x_level!=1)
            $multi_key[$x_tag][$x_level]++;
        while ($start_level < $x_level) {
            $php_stmt .= '[$level['.$start_level.']]';
            if (isset($multi_key[$level[$start_level]][$start_level]) && $multi_key[$level[$start_level]][$start_level])
                $php_stmt .= '['.($multi_key[$level[$start_level]][$start_level]-1).']';
            $start_level++;
        }
        $add='';
        if (isset($multi_key[$x_tag][$x_level]) && $multi_key[$x_tag][$x_level] && ($x_type=='open' || $x_type=='complete')) {
            if (!isset($multi_key2[$x_tag][$x_level]))
                $multi_key2[$x_tag][$x_level]=0;
            else
                $multi_key2[$x_tag][$x_level]++;
            $add='['.$multi_key2[$x_tag][$x_level].']';
        }
        if (isset($xml_elem['value']) && trim($xml_elem['value'])!='' && !array_key_exists('attributes', $xml_elem)) {
            if ($x_type == 'open')
                $php_stmt_main=$php_stmt.'[$x_type]'.$add.'[\'content\'] = $xml_elem[\'value\'];';
            else
                $php_stmt_main=$php_stmt.'[$x_tag]'.$add.' = $xml_elem[\'value\'];';
            eval($php_stmt_main);
        }
        if (array_key_exists('attributes', $xml_elem)) {
            if (isset($xml_elem['value'])) {
                $php_stmt_main=$php_stmt.'[$x_tag]'.$add.'[\'content\'] = $xml_elem[\'value\'];';
                eval($php_stmt_main);
            }
            foreach ($xml_elem['attributes'] as $key=>$value) {
                $php_stmt_att=$php_stmt.'[$x_tag]'.$add.'[$key] = $value;';
                eval($php_stmt_att);
            }
        }
    }
    return $xml_array;
}
?>
NexusRex
  • 2,152
  • 17
  • 14
19

Hi I think the SimpleXml is very useful . And with it I am using xpath;

$xml = simplexml_load_file("som_xml.xml");

$blocks  = $xml->xpath('//block'); //gets all <block/> tags
$blocks2 = $xml->xpath('//layout/block'); //gets all <block/> which parent are   <layout/>  tags

I use many xml configs and this helps me to parse them really fast. SimpleXml is written on C so it's very fast.

George G
  • 7,443
  • 12
  • 45
  • 59
Vahan
  • 524
  • 1
  • 6
  • 22
13

It depends on what you are trying to do with the XML files. If you are just trying to read the XML file (like a configuration file), The Wicked Flea is correct in suggesting SimpleXML since it creates what amounts to nested ArrayObjects. e.g. value will be accessible by $xml->root->child.

If you are looking to manipulate the XML files you're probably best off using DOM XML

dcousineau
  • 2,202
  • 18
  • 24
0

the crxml parser is a real easy to parser.

This class has got a search function, which takes a node name with any namespace as an argument. It searches the xml for the node and prints out the access statement to access that node using this class. This class also makes xml generation very easy.

you can download this class at

http://freshmeat.net/projects/crxml

or from phpclasses.org

http://www.phpclasses.org/package/6769-PHP-Manipulate-XML-documents-as-array.html