Posts Tagged XML

PHP Class for converting XML to Object and Object to XML

Sometimes in PHP we need to convert PHP object into XML string and vice versa. Conversion of XML string to PHP object is pretty simple. You just need to call simplexml_load_string() function (available in PHP 5+) and need to pass your XML string. This will return the object which you can use. The only requirement is your XML string need to be well-formed XML string otherwise PHP will through E_WARNING error message.

Conversion of Object into XML string is little bit tricky. We need to recursively parse the Object and need to create XML tags for object attributes (keys). I’m using XmlWriter class for that purpose. Three important methods of this class which I’m using is startElement(), endElement(), and writeElement(). We need to check the passed mixed variable in getObject2XML() method and add the XML tags with values one by one.

<?php
class ObjectAndXML {
	private static $xml;
 
	// Constructor
	public function __construct() {
		$this->xml = new XmlWriter();
		$this->xml->openMemory();
		$this->xml->startDocument('1.0');
		$this->xml->setIndent(true);
	}
 
	// Method to convert Object into XML string
	public function objToXML($obj) {
		$this->getObject2XML($this->xml, $obj);
 
		$this->xml->endElement();
 
		return $this->xml->outputMemory(true);
	}
 
	// Method to convert XML string into Object
	public function xmlToObj($xmlString) {
		return simplexml_load_string($xmlString);
	}
 
	private function getObject2XML(XMLWriter $xml, $data) {
		foreach($data as $key => $value) {
			if(is_object($value)) {
				$xml->startElement($key);
				$this->getObject2XML($xml, $value);
				$xml->endElement();
				continue;
			}
			else if(is_array($value)) {
				$this->getArray2XML($xml, $key, $value);
			}
 
			if (is_string($value)) {
				$xml->writeElement($key, $value);
			}
		}
	}
 
	private function getArray2XML(XMLWriter $xml, $keyParent, $data) {
		foreach($data as $key => $value) {
			if (is_string($value)) {
				$xml->writeElement($keyParent, $value);
				continue;
			}
 
			if (is_numeric($key)) {
				$xml->startElement($keyParent);
			}
 
			if(is_object($value)) {
				$this->getObject2XML($xml, $value);
			}
			else if(is_array($value)) {
				$this->getArray2XML($xml, $key, $value);
				continue;
			}
 
			if (is_numeric($key)) {
				$xml->endElement();
			}
		}
	}
}
?>

How to use it.
1. If you want to convert XML string into PHP object.

<?php
$obj = new ObjectAndXML();
 
$str = <<<STR
<?xml version="1.0" encoding="utf-8"?>
<records>
    <person>
    	<name>XYZ</name>
        <age>28</age>
        <gender>Male</gender>
    </person>
    <person>
    	<name>ABC</name>
        <age>25</age>
        <gender>Male</gender>
    </person>
</records>
STR;
 
$recordsObj = $obj->xmlToObj($str);
echo '<pre>';
var_dump($recordsObj);
 
// Above code will give you this output on browser
/*
object(SimpleXMLElement)#3 (1) {
  ["person"]=>
  array(2) {
    [0]=>
    object(SimpleXMLElement)#4 (3) {
      ["name"]=>
      string(3) "XYZ"
      ["age"]=>
      string(2) "28"
      ["gender"]=>
      string(4) "Male"
    }
    [1]=>
    object(SimpleXMLElement)#5 (3) {
      ["name"]=>
      string(3) "ABC"
      ["age"]=>
      string(2) "25"
      ["gender"]=>
      string(4) "Male"
    }
  }
}
*/
 
// If you want to access value of "name" tag under second "person" tag then you can use 
echo $recordsObj->person[1]->name;
?>

2. If you want to convert PHP object into XML string.

<?php
$obj = new ObjectAndXML();
 
$objData1 = new stdClass;
 
$objData1->records->person[0]->name = 'XYZ';
$objData1->records->person[0]->age = '28';
$objData1->records->person[0]->gender = 'Male';
 
$objData1->records->person[1]->name = 'ABC';
$objData1->records->person[1]->age = '25';
$objData1->records->person[1]->gender = 'Male';
 
echo $recordsXML = $obj->objToXML($objData1);
 
// Output will be
/*
<?xml version="1.0"?>
<records>
 <person>
  <name>XYZ</name>
  <age>28</age>
  <gender>Male</gender>
 </person>
 <person>
  <name>ABC</name>
  <age>25</age>
  <gender>Male</gender>
 </person>
</records>
*/
 
$objData2 = new stdClass;
 
$objData2->records->person[0]->name[] = 'XYZ';
$objData2->records->person[0]->name[] = 'ABC';
$objData2->records->person[0]->name[] = 'PQR';
 
$objData2->records->person[1]->name[] = 'XYZ1';
$objData2->records->person[1]->name[] = 'ABC1';
$objData2->records->person[1]->name[] = 'PQR1';
 
echo $recordsXML = $obj->objToXML($objData2);
 
// Output will be
/*
<?xml version="1.0"?>
<records>
 <person>
  <name>XYZ</name>
  <name>ABC</name>
  <name>PQR</name>
 </person>
 <person>
  <name>XYZ1</name>
  <name>ABC1</name>
  <name>PQR1</name>
 </person>
</records>
*/
 
$objData3 = new stdClass;
 
$objData3->records->person->name = 'XYZ';
$objData3->records->person->age = '28';
$objData3->records->person->gender = 'Male';
 
echo $recordsXML = $obj->objToXML($objData3);
 
// Output will be
/*
<?xml version="1.0"?>
<records>
 <person>
  <name>XYZ</name>
  <age>28</age>
  <gender>Male</gender>
 </person>
</records>
*/
?>

, ,

2 Comments


Convert XML to Array using DOM extension in PHP5

The xml2array class convert the XML stored in a string into an ARRAY. We are using the DOM extension of PHP5. The DOM extension replaced the DOM XML extension available in PHP4. The DOM XML extension is depreciated in PHP5.

<?php
class xml2array {
 
	function xml2array($xml) {
		if (is_string($xml)) {
			$this->dom = new DOMDocument;
			$this->dom->loadXml($xml);
		}
 
		return FALSE;
	}
 
	function _process($node) { 
		$occurance = array();
 
		foreach($node->childNodes as $child) {
			$occurance[$child->nodeName]++;
		}
 
		if($node->nodeType == XML_TEXT_NODE) { 
			$result = html_entity_decode(htmlentities($node->nodeValue, ENT_COMPAT, 'UTF-8'), 
                                     ENT_COMPAT,'ISO-8859-15');
		} 
		else {
			if($node->hasChildNodes()){
				$children = $node->childNodes;
 
				for($i=0; $i<$children->length; $i++) {
					$child = $children->item($i);
 
					if($child->nodeName != '#text') {
						if($occurance[$child->nodeName] > 1) {
							$result[$child->nodeName][] = $this->_process($child);
						}
						else {
							$result[$child->nodeName] = $this->_process($child);
						}
					}
					else if ($child->nodeName == '#text') {
						$text = $this->_process($child);
 
						if (trim($text) != '') {
							$result[$child->nodeName] = $this->_process($child);
						}
					}
				}
			} 
 
			if($node->hasAttributes()) { 
				$attributes = $node->attributes;
 
				if(!is_null($attributes)) {
					foreach ($attributes as $key => $attr) {
						$result["@".$attr->name] = $attr->value;
					}
				}
			}
		}
 
		return $result;
	}
 
	function getResult() {
		return $this->_process($this->dom);
	}
}
?>

We can use this class like this.

<?php
	$obj = new xml2array($XML_string);
	$XML_array = $obj->getResult();
?>

, ,

5 Comments