array to xml to array

Array to Xml Conversion and Xml to Array Convert in PHP

Hi Geeks,
Today i am sharing you a code snippet for converting xml to array with attributes also and vice versa (Convert array to xml). This class is very useful to parse rss feed and to make rss feed in php programming.

In this code snippet we have made a class to convert array XML using php code and also retaining its attibues stored into array . It returns the XML in form of DOMDocument class for further manipulation. This class will throw exception if the tag name or attribute name has illegal characters.

Usage of this class:

 //convert array to xml//
		$php_array = array ();//this is your array data ,it comes from database also or you can define elements in php code also.
	    $root_node="ROOT";//root node of the xml tree like//root , data or anything you want to make super parent tag for the xml
        $xml = Array2XML::createXML($root_node, $php_array);//
        echo $xml->saveXML();
	   
	  //convert  xml to array//
		$xmlstring='';//this varribale will contain xml string
		$xml_data = Array2XML::XML_TO_ARR($xmlstring);//
        

A. Steps for Convert Array to Xml

1.Create a class named Array2XML with following code in file Array2XML.php

<?php

class Array2XML {
 
    private static $xml = null;
	private static $encoding = 'UTF-8';
 
    /**
     * Initialize the root XML node [optional]
     * @param $version
     * @param $encoding
     * @param $format_output
     */
    public static function init($version = '1.0', $encoding = 'UTF-8', $format_output = true) {
        self::$xml = new DomDocument($version, $encoding);
        self::$xml->formatOutput = $format_output;
		self::$encoding = $encoding;
    }
 
    /**
     * Convert an Array to XML
     * @param string $node_name - name of the root node to be converted
     * @param array $arr - aray to be converterd
     * @return DomDocument
     */
    public static function &createXML($node_name, $arr=array()) {
        $xml = self::getXMLRoot();
        $xml->appendChild(self::convert($node_name, $arr));
 
        self::$xml = null;    // clear the xml node in the class for 2nd time use.
        return $xml;
    }
 
    /**
     * Convert an Array to XML
     * @param string $node_name - name of the root node to be converted
     * @param array $arr - aray to be converterd
     * @return DOMNode
     */
    private static function &convert($node_name, $arr=array()) {
 
        //print_arr($node_name);
        $xml = self::getXMLRoot();
        $node = $xml->createElement($node_name);
 
        if(is_array($arr)){
            // get the attributes first.;
            if(isset($arr['@attributes'])) {
                foreach($arr['@attributes'] as $key => $value) {
                    if(!self::isValidTagName($key)) {
                        throw new Exception('[Array2XML] Illegal character in attribute name. attribute: '.$key.' in node: '.$node_name);
                    }
                    $node->setAttribute($key, self::bool2str($value));
                }
                unset($arr['@attributes']); //remove the key from the array once done.
            }
 
            // check if it has a value stored in @value, if yes store the value and return
            // else check if its directly stored as string
            if(isset($arr['@value'])) {
                $node->appendChild($xml->createTextNode(self::bool2str($arr['@value'])));
                unset($arr['@value']);    //remove the key from the array once done.
                //return from recursion, as a note with value cannot have child nodes.
                return $node;
            } else if(isset($arr['@cdata'])) {
                $node->appendChild($xml->createCDATASection(self::bool2str($arr['@cdata'])));
                unset($arr['@cdata']);    //remove the key from the array once done.
                //return from recursion, as a note with cdata cannot have child nodes.
                return $node;
            }
        }
 
        //create subnodes using recursion
        if(is_array($arr)){
            // recurse to get the node for that key
            foreach($arr as $key=>$value){
                if(!self::isValidTagName($key)) {
                    throw new Exception('[Array2XML] Illegal character in tag name. tag: '.$key.' in node: '.$node_name);
                }
                if(is_array($value) && is_numeric(key($value))) {
                    // MORE THAN ONE NODE OF ITS KIND;
                    // if the new array is numeric index, means it is array of nodes of the same kind
                    // it should follow the parent key name
                    foreach($value as $k=>$v){
                        $node->appendChild(self::convert($key, $v));
                    }
                } else {
                    // ONLY ONE NODE OF ITS KIND
                    $node->appendChild(self::convert($key, $value));
                }
                unset($arr[$key]); //remove the key from the array once done.
            }
        }
 
        // after we are done with all the keys in the array (if it is one)
        // we check if it has any text value, if yes, append it.
        if(!is_array($arr)) {
            $node->appendChild($xml->createTextNode(self::bool2str($arr)));
        }
 
        return $node;
    }
 
    /*
     * Get the root XML node, if there isn't one, create it.
     */
    private static function getXMLRoot(){
        if(empty(self::$xml)) {
            self::init();
        }
        return self::$xml;
    }
 
    /*
     * Get string representation of boolean value
     */
    private static function bool2str($v){
        //convert boolean to text value.
        $v = $v === true ? 'true' : $v;
        $v = $v === false ? 'false' : $v;
        return $v;
    }
 
    /*
     * Check if the tag name or attribute name contains illegal characters
     * Ref: http://www.w3.org/TR/xml/#sec-common-syn
     */
    private static function isValidTagName($tag){
        $pattern = '/^[a-z_]+[a-z0-9\:\-\.\_]*[^:]*$/i';
        return preg_match($pattern, $tag, $matches) && $matches[0] == $tag;
    } 
	
	/*
     * Convert xml string into array.
     */
    public static function XML_TO_ARR($xmlstring)
	{
		$xml = simplexml_load_string($xmlstring, "SimpleXMLElement", LIBXML_NOCDATA);
		$json = json_encode($xml);
		$array = json_decode($json,TRUE);
		return $array;
    }
}
?>

2. Now Include the class

<?php

include 'Array2XML.php';//include with path to your class file 'Array2XML'

?>

3. Defining Array or get it from database then call the createXML method for generating xml file

$data_array = array(
    '@attributes' => array(
        'type' => 'fiction'
    ),
    'book' => array(
        array(
            '@attributes' => array(
                'author' => 'Jeetendra Singh'
            ),
            'title' => 'Learning PHP programming',
            'price' => 'Free'
        ),
        array(
            '@attributes' => array(
                'author' => 'Shailesh Verma'
            ),
            'title' => 'Linux Aspects',
            'price' => '$15.61'
        ),
        array(
            '@attributes' => array(
                'author' => 'Eric Basendra'
            ),
            'title' => 'IOS Dev',
            'Company' => 'Oxilo India',
            'price' => array(
                '@attributes' => array(
                    'discount' => '10%'
                ),
                '@value' => '$18.00'
            )
        )
    )
);

Now Call createXML method as following

  $root_node="data";//root node of the xml tree like//root , data or anything you want to make super parent tag for the xml
  $xml = Array2XML::createXML($root_node, $data_array);//
  
  $xml_STR = $xml->saveXML();// put string in xml_STR
  $xml->save('array_to_xml_convert.xml'); // save data in array_to_xml_convert.xml file

B. Steps for Convert Xml to Array

1. Define the xml oe get the xml string into a varribale

$xmlstring='<?xml version="1.0"?>
<x>
  <hello>4</hello>
  <var name="the-name" attr2="something-else">
    <n0>first</n0>
    <n1>second</n1>
    <n5>fifth</n5>
    <sub x="4.356" y="-9.2252">
      <n0>sub1</n0>
      <n1>sub2</n1>
      <n2>sub3</n2>
    </sub>
  </var>
  <foo>1234</foo>
</x>';

Or

$xmlstring=file_get_contents('myxml_file_path.xml');//get the string load into a varriable using 
file_get_contents method of php

2.Now call the XML_TO_ARR function as following

$Array_Data = Array2XML::XML_TO_ARR($xmlstring);//pass the xml string 
print_r($Array_Data);//print your array

[viraldownloader id=138 text=’DOWNLOAD COMPLETE CODE’]

Published by

Jeetendra Singh

Jeetendra Singh is a Full Stack Architect who has 12+ Years of Experience into Software Development. He is a Microsoft certified technology Specialist and AWS Certified Associate Architect. His Major Interests are in Mongo Db, Express Js, React Js, Node Js (MERN STACK), Python, DJango, Redis, Mysql, Dynamo DB , Devops, Jenkins, Cloud/Lamda , Fast Api. He build variety of applications using Python, Mern, Mean, Node, JavaScript, jQuery & PHP