Array2XML: convert PHP Array to XML (with attributes and CDATA)

Array2XML is a class to convert an array in PHP to XML. It allows you to parse a multidimensional array into XML including attributes unlike other scripts available on the internet. It returns the XML in form of DOMDocument object for further manipulation.

This library is very helpful when you know the scheme before hand and you have to generate an XML for it using dynamic values from the database.

The resulting XML can be converted back to an Array using the XML2Array class.

Usage

The usage is pretty simple. You have to include the class file in your code and call the following function.

$xml = Array2XML::createXML('root_node_name', $php_array);
echo $xml->saveXML();

Important thing to note is that the $xml object returned is of type DOMDocument and hence you can perform further operations on it.

Optionally you can also set the version of XML and encoding by calling the Array2XML::init() function before calling the Array2XML::createXML() function.

Array2XML::init($version /* ='1.0' */, $encoding /* ='UTF-8' */);

It throws exception if the tag name or attribute name has illegal chars as per W3C spec.

Array Structure conventions

The array passed to the Array2XML::createXML() function follows few conventions, which are quite literal and easy to learn/use. The examples below demonstrate their usage

  1. Empty Nodes: Following will create an empty node.
    $books = array();  // or
    $books = null;  // or
    $books = '';
    $xml = Array2XML::createXML('books', $books);
     
    // all three cases above create <books/>
  2. Attributes: Attributes can be added to any node by having a @attributes key in the array
    $books = array(
        '@attributes' => array(
            'type' => 'fiction',
            'year' => 2011,
            'bestsellers' => true
        )
    );
    $xml = Array2XML::createXML('books', $books);
     
    // creates <books type="fiction" year="2011" bestsellers="true"/>
  3. Node Value: For nodes without attributes, value can be assigned directly, else we need to have a @value key in the array. Following examples will make it clear
    $books = 1984;  // or
    $books = array(
        '@value' = 1984
    );
    // creates <books>1984</books>
     
    $books = array(
        '@attributes' => array(
            'type' => 'fiction'
        ),
        '@value' = 1984
    );
    // creates <books type="fiction">1984</books>
     
    $books = array(
        '@attributes' => array(
            'type' => 'fiction'
        ),
        'book' => 1984
    );
    /* creates 
    <books type="fiction">
      <book>1984</book>
    </books>
    */
     
    $books = array(
        '@attributes' => array(
            'type' => 'fiction'
        ),
        'book'=> array('1984','Foundation','Stranger in a Strange Land')
    );
    /* creates 
    <books type="fiction">
      <book>1984</book>
      <book>Foundation</book>
      <book>Stranger in a Strange Land</book>
    </books>
    */
  4. Complex XML: Following example clarifies most of the usage of the library
    $books = array(
        '@attributes' => array(
            'type' => 'fiction'
        ),
        'book' => array(
            array(
                '@attributes' => array(
                    'author' => 'George Orwell'
                ),
                'title' => '1984'
            ),
            array(
                '@attributes' => array(
                    'author' => 'Isaac Asimov'
                ),
                'title' => array('@cdata'=>'Foundation'),
                'price' => '$15.61'
            ),
            array(
                '@attributes' => array(
                    'author' => 'Robert A Heinlein'
                ),
                'title' =>  array('@cdata'=>'Stranger in a Strange Land'),
                'price' => array(
                    '@attributes' => array(
                        'discount' => '10%'
                    ),
                    '@value' => '$18.00'
                )
            )
        )
    );
    /* creates 
    <books type="fiction">
      <book author="George Orwell">
        <title>1984</title>
      </book>
      <book author="Isaac Asimov">
        <title><![CDATA[Foundation]]></title>
        <price>$15.61</price>
      </book>
      <book author="Robert A Heinlein">
        <title><![CDATA[Stranger in a Strange Land]]</title>
        <price discount="10%">$18.00</price>
      </book>
    </books>
    */

Detailed Example

You can see a much more detailed example here.

Download (v0.5, 07 Dec, 2011)

The code is released under Apache License 2.0

Plaint text PHP source (v0.5) | Formatted PHP source (v0.5)

• • •

32 Responses to Array2XML: convert PHP Array to XML (with attributes and CDATA)

  1. Chris Neal says:

    This works perfectly. Good job!

  2. Tim Lee says:

    Do you know of any good class to do the reverse? Convert xml into an array?

    Thanks,

  3. Lion says:

    Thanks,

  4. Pete says:

    I tried 1/2 dozen of these and this is the only one that actually worked!

    Great job!

    Thanks for sharing!

  5. Liel Dulev says:

    Hi, Great Class, but I found a bug:

    You should always use

    htmlspecialchars($value,ENT_QUOTES,'UTF-8');

    and not

    htmlentities($value);

    in XML, as htmlentities replaces chars that should not be replaced and it breaks the xml.

    • Ben says:

      Using PHP version

      I ran into a problem of double encoding with your code. You are encoding the xml string into things like DOMText nodes and DOMAttr values. When you call saveXML() on the DOMDocument, it encodes your already encoded string resulting in things like &amp;. This isn’t what should be expected.

      Just wanted to let you know. :)

  6. Liel Dulev says:

    Another Bug:

    on line 108 it should be

    if(!empty($arr) || $arr===false) { ... }

    otherwise you will get empty nodes and not nodes with the value of false…

  7. chrisA says:

    Hi, thanks for the class. I want to use your xml class for generating of xml document to use with a Rest service. The root name has a URL attached. something like this:

    how can i have something like above as/in the root name, not just

  8. ChrisA says:

    I have seen the solution in the advance examples, the resturant example answered by question. Thanks

  9. ChrisA says:

    I am having error with this class in that i can not use ‘v’ as an attribute?
    I want to use a web service api that required that i send a “v” but array2xml doesn’t let me do that it will accept everything but not ‘v’ as an attribute “v” meaning version number.

    how can i solve this problem?

    • Lalit says:

      Fixed the regex which didn’t allow tag names which are single character in length. This should work now.
      Thanks for pointing it out. Please take the new version (0.3) of the file.

  10. Mario says:

    Has anyone found a solution for using CDATA?

  11. Anny says:

    Hi Lalit, I needed to use your class in a Magento project so adapted it to fit while also restructuring bits of code to make it more human-readable and I think a little easier to use as a developer. You can find the source code here, https://github.com/annyfm/Anny_Array2xml/blob/master/app/code/community/Anny/Array2xml/Model/Converter.php and I’ve preserved your license information and version notes with a link back to this page. Hope you find it interesting!

  12. Pingback: Ligio Blog » Array to XML in PHP

  13. Eddie says:

    Just what I was looking for, searched for ages to find a nice simple solution like this!

    Many thanks :)

  14. jagan says:

    Hi Lalit,

    I am trying to use your class but I have arrays for [@value], and it is failing how do I use if the [@value] is another array?

    Please let me know.

    Thanks,

    • Lalit says:

      Hi Jagan,
      If you need value to be an array you just need to directly name the attribute with the node name, no need to use @value.
      Example:

      $xml['node_name'][] = 'value1'; 
      $xml['node_name'][] = 'value2';
  15. m0rfeusl says:

    Great thanks for this perfect solution! You are master ;)

  16. majki says:

    You saved my ass!!! You are my hero

  17. Tim Lee says:

    Thank you very much for this class, it has helped me greatly. I did have one issue with the cdata processing though (it doesn’t seem to process cdata when it’s in a node that has the same name as the surrounding nodes), would you be able to assist me with this?

    The array I give it is this:

    $input = array(
                "show" => array(
                    array(
                        "dog" => "Brian",
                        "kid" => array(
                            "Chris",
                            "Meg",
                            "@cdata" => "<em>Stewie</em>"
                        ),
                        "@attributes" => array("name" => "Family Guy")
                    ),
                    array(
                        "empty" => array(),
                        "foo" => array(
                            "@attributes" => array(
                                "empty" => ""
                            )
                        ),
                        "zero" => "0",
                        "@attributes" => array(
                            "name" => "Edge Cases",
                            "zero" => "0",
                            "empty" => ""
                        )
                    )
                ),
            );

    With a node name of “tv”, I get the following XML:

    ...
        <dog>Brian</dog>
        <kid>Chris
        <kid>Meg
        <kid>&amp;lt;em&amp;gt;Stewie&amp;lt;/em&amp;gt;</kid>
    ...

    Is this format of cdata something that could be accommodated?

    Thanks,
    Tim Lee

  18. What such a nice class, thanks for your works.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">