Simple XML (SimpleXML) Tutorial Part 1 By Will Fitch 23 April 2008 at 9:40 pm

With the increasing use of web services and communications via HTTP, XML has become an industry standard for sending and receiving data among systems. Every language seems to have multiple ways to parse XML, each more complicated than the other. This presents a problem for developers.

The majority of the time, developers need to read/write XML files without complex features such as advanced namespacing and XSD validation. It seems that opening an XML file, reading and using the content takes forever as you constantly need to reference hundreds of pages of documentation, Google examples of each method or function in the documentation; it never ends.

Since the release of PHP5, SimpleXML has been available for creating and editing XML files or strings. Don’t let the name fool you, it doesn’t represent the simplicity of its capabilities. It does, however, mean the implementation of this extension is simple! PHP has other XML capabilities such as DOM, XMLWriter and XMLReader in the event you need those advanced features not offered by the native SimpleXML extension.

Configuring PHP to Use SimpleXML

SimpleXML is an extension that was added as of PHP 5 and requires no special libraries. If for some reason you wish not to have SimpleXML available to your PHP configuration, you can disable it at compile-time using --disable-simplexml. The primary class you will work with is called SimpleXMLElement.

There are Four Ways to Get an Instance of SimpleXMLElement:

  1. simplexml_load_file - Load an XML document from a file. You may also access a remote file (HTTP for example).
  2. simplexml_load_string - Load and XML string. Please keep in mind the XML needs to be well-formed.
  3. SimpleXMLElement - Directly instantiate the SimpleXMLElement class. This requires a parameter starting the XML document. If you directly instantiate this class, you are typically using SimpleXML for XML output.
  4. simplexml_import_dom - Returns and instance of SimpleXMLElement from a DOM object. That’s right, you can bring over that advanced object and make life simple!

Sample XML File Used

The following XML data will be contained in the referenced “test_file.xml”:

XML
  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <cars>
  3.         <make name="Ford">
  4.                 <model>Mustang</model>
  5.         </make>
  6.         <make name="Honda">
  7.                 <model>Accord</model>
  8.         </make>
  9. </cars>

Loading XML Data Using simplexml_load_file

This function is typically used for loading XML data either from a file, or a remote call. In this example, we will load a flat XML file:

PHP
  1. <?php
  2. // Location of the XML file on the file system
  3. $file = ‘test_file.xml’;
  4. $xml = simplexml_load_file($file);
  5. ?>

That’s it. No need to clean anything up, PHP will take care of that for you.

Loading XML Using simplexml_load_string

PHP
  1. <?php
  2. // XML String
  3. $xml =
  4. <?xml version="1.0" encoding="ISO-8859-1"?>
  5. <cars>
  6.         <make name="Ford">
  7.                 <model>Mustang</model>
  8.         </make>
  9.         <make name="Honda">
  10.                 <model>Accord</model>
  11.         </make>
  12. </cars>
  13. ;
  14. $xml = simplexml_load_string($xml);
  15. ?>

Pretty easy, huh? This function loads an XML string and returns and instance of SimpleXMLElement. You could also directly instantiate the SimpleXMLElement class a similar way, as demonstrated below.

Loading XML Using the SimpleXMLElement Class

PHP
  1. <?php
  2. $xml =
  3. <?xml version="1.0" encoding="ISO-8859-1"?>
  4. <cars>
  5.         <make name="Ford">
  6.                 <model>Mustang</model>
  7.         </make>
  8.         <make name="Honda">
  9.                 <model>Accord</model>
  10.         </make>
  11. </cars>
  12. ;
  13. $xml = new SimpleXMLElement($xml);
  14. ?>

It’s your choice on using this method, or simplexml_load_string.

Loading XML Data Using simplexml_import_dom

PHP
  1. <?php
  2. $xml =
  3. <?xml version="1.0" encoding="ISO-8859-1"?>
  4. <cars>
  5.         <make name="Ford">
  6.                 <model>Mustang</model>
  7.         </make>
  8.         <make name="Honda">
  9.                 <model>Accord</model>
  10.         </make>
  11. </cars>
  12. ;
  13. $dom = new DOMDocument;
  14. $dom->loadXML($xml);
  15. $xml = simplexml_import_dom($dom);
  16. ?>

This is handy when you are working with the advanced XML features of DOM. When you’re ready to move from those precocious features, just load the DOM object into simplexml_import_dom, and start programming the easy way!

Loading XML Data Using simplexml_load_file

PHP
  1. <?php
  2. $file = ‘test_file.xml’;
  3. $xml = simplexml_load_file($file);
  4. /*
  5. The $xml object now has the top, parent node <cars>
  6. All nodes are referenced as properties, and node attributes are within an associative array in each of those properties. 
  7. If there are multiple nodes with the same name (<make> in this example), you will need to specify the index value to reference.  This is done as an array index.  The following code refences the "name" attribute in the first <make> node
  8. */
  9. echo $xml->make[0][‘name’];
  10. // Prints out "Ford" (without quotes)
  11. ?>

The above example print out “Ford”. We referenced the first node, and then printed out the “name” attribute. Now, let’s print out “Mustang” from the node.

PHP
  1. <?php
  2. $file = ‘test_file.xml’;
  3. $xml = simplexml_load_file($file);
  4. echo $xml->make[0]->model;
  5. // Prints out "Mustang" (without quotes)
  6. ?>

Reading XML doesn’t get any easier. The object-oriented design provided by SimpleXML makes code very elegant and maintainable.

The above examples assume you know exactly which node, down to the index, that contains the data you need to access. In the real world, this is an unlikely scenario. Normally, a developer knows the node names they are working with, but do not know (nor care) as to the number of those nodes.

Just like with normal arrays, we can count the number of elements. We will do this prior to iterating over the node. Let’s iterate!

PHP
  1. <?php
  2. $xml =
  3. <?xml version="1.0" encoding="ISO-8859-1"?>
  4. <cars>
  5.         <make name="Ford">
  6.                 <model>Mustang</model>
  7.         </make>
  8.         <make name="Honda">
  9.                 <model>Accord</model>
  10.         </make>
  11. </cars>’;
  12. $xml = simplexml_load_string($xml);
  13. if (count($xml->make) > 0) {
  14.     foreach ($xml->make as $node) {
  15.         // This prints out each of the models
  16.         echo $node->model.chr(10);
  17.     }
  18. }
  19. ?>

Important Information Regarding Values Returned from SimpleXML

If you have debugged any of these examples, you would have noticed that everything, nodes and attributes, are an instance of SimpleXMLElement. This may or may not be a feature in your opinion, but it’s the nature of SimpleXML. If you plan on storing any of these node/attribute values, you will need to typecast them:

PHP
  1. <?php
  2. $xml = ‘test_file.xml’;
  3. $xml = simplexml_load_file($xml);
  4. $value_to_store = (string) $xml->make[0]->model;
  5. // This converts the "Mustang" SimpleXMLElement object to a string, making it disk storable.
  6. ?>

You should certainly keep this in mind as you are working with this extension.

Writing XML with SimpleXML

Writing or producing XML is just as easy as reading it. While you can add additional data to existing XML files, the examples in this section will create fresh XML data. In part two, we will discuss more advanced options such as DOM, CDATA and namespaces. Now, on to writing XML data.

You will quickly learn that SimpleXML expects well-formed XML. There are two PHP functions you should familiarize with if you are not already:

  1. utf8_encode - encode a string with UTF-8 standards.
  2. htmlspecialchars - encode HTML characters with their proper entities.

You will need to use htmlspecialchars followed by utf8_encode to ensure proper data encoding. The following example illustrates using this technique to ensure proper XML output:

PHP
  1. <?php
  2. $xml = new SimpleXMLElement(‘<cars></cars>’);
  3. $make = $xml->addChild(‘make’);
  4. $make->addAttribute(‘name’,‘Ford’);
  5. $make->addChild(‘model’,htmlspecialchars(utf8_encode($some_db_variable)));
  6. $xml->asXML();
  7. // This will output the XML
  8. ?>

In order to create a new instance of SimpleXMLElement for writing, you will need to specify the top parent node. No need for the XML declaration, SimpleXML will add this for you. In the above example, we ensured that data coming from a database variable had non-UTF8 encoded characters encoded, and HTML entities properly converted. We also introduced a few additional methods. Let me explain:

The addChild method adds a new child to an existing node. This takes an optional second parameter of the value to place inside that node.

Each time you create a new child, a reference to the SimpleXMLElement is returned for use. Here, you can add additional child nodes, attributes and more. The initial SimpleXML object ($xml in the above example) contains the primary instance. You will use this object to output the data.

The addAttribute method adds an attribute to a node. If you aren’t sure of the data being added to the attribute (and just to be safe), you should also encode that value.

The asXML method saves/outputs the XML to the proper buffer. If you specify a file name in this method, the XML will be written to it. Here is an example:

PHP
  1. <?php
  2. $xml = new SimpleXMLElement(‘<cars></cars>’);
  3. $make = $xml->addChild(‘make’);
  4. $make->addAttribute(‘name’,‘Ford’);
  5. $make->addChild(‘model’,htmlspecialchars(utf8_encode($some_db_variable)));
  6. $xml->asXML(‘test_file.xml’);
  7. // This will save the XML to a file called test_file.xml
  8. ?>

Conclusion

Through examples and definitions, you have familiarized yourself with the basics of SimpleXML. In part two (which is written yet), I will explain more advanced features of SimpleXML and DOM.

If you have any questions, feel free to post comments.

Will

[del.icio.us] [Digg] [dzone] [Furl] [Google] [Reddit] [Slashdot] [Sphere] [Yahoo!]
Add comment

2 responses : “ Simple XML (SimpleXML) Tutorial Part 1 ”

  1. 1
    Carlton Dickson :

    Thanks for a great article…just studying for the ZCE so this will come in handy for the XML section.
    Have added your blog to my PHP RSS feeds too….great design and content.

    p.s. In the section “There are four ways to get an instance of SimpleXMLElement:” you used simplexml_dom_import instead of simplexml_import_dom

  2. 2
    Will Fitch :

    Good catch, Carlton. I have made the typo correction.

    I will post some articles regarding the Zend Certification Exam next week.

Leave a Reply