PHP programming - XML Interface
Frank Yap

XML interface examples are shown in this section.
 
Resources

 
Lab Exercises
Exercise 1: Interfacing with XML

In this section we will show an example of interfacing with XML.
 
But first let's see how the SimpleXMLElement object is encoded. When we call simplexml_load_string() function it returns a SimpleXMLElement.
Below we have an XML string. We will get a SimpleXMLElement by calling simplexml_load_string() function with the string, and we will display the internals of the returned SimpleXMLElement.
 
<?xml version="1.0"?> 
<Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
xmlns:x="urn:schemas-microsoft-com:office:excel"> 
<Worksheet ss:Name="maCitiesGps"> 
<Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="10"> 
<Column ss:AutoFitWidth="0" ss:Width="110.25"/> 
<Column ss:AutoFitWidth="0" ss:Width="78" ss:Span="1"/> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Acton, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.485819999999997</Data></Cell> 
<Cell><Data ss:Type="Number">-71.433299000000005</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Berkley, MA</Data></Cell> 
<Cell><Data ss:Type="Number">41.846356999999998</Data></Cell> 
<Cell><Data ss:Type="Number">-71.082538999999997</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Boston, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.358635</Data></Cell> 
<Cell><Data ss:Type="Number">-71.056698999999995</Data></Cell> 
</Row> 
</Table> 
</Worksheet> 
</Workbook>
 
The prefix ss: are the namespaces used to avoid name collisions.
 
Let's get XML element and print_r for details.
 
// Get SimpleXMLElement
$Workbook = simplexml_load_string ($strXml);

Print out of print_r ($Workbook):

SimpleXMLElement Object ( [Worksheet] => SimpleXMLElement Object ( [Table] => SimpleXMLElement Object ( [Column] => Array ( [0] => SimpleXMLElement Object ( ) [1] => SimpleXMLElement Object ( ) ) [Row] => Array ( [0] => SimpleXMLElement Object ( [Cell] => Array ( [0] => SimpleXMLElement Object ( [Data] => Acton, MA ) [1] => SimpleXMLElement Object ( [Data] => 42.485819999999997 ) [2] => SimpleXMLElement Object ( [Data] => -71.433299000000005 ) ) ) [1] => SimpleXMLElement Object ( [Cell] => Array ( [0] => SimpleXMLElement Object ( [Data] => Berkley, MA ) [1] => SimpleXMLElement Object ( [Data] => 41.846356999999998 ) [2] => SimpleXMLElement Object ( [Data] => -71.082538999999997 ) ) ) [2] => SimpleXMLElement Object ( [Cell] => Array ( [0] => SimpleXMLElement Object ( [Data] => Boston, MA ) [1] => SimpleXMLElement Object ( [Data] => 42.358635 ) [2] => SimpleXMLElement Object ( [Data] => -71.056698999999995 ) ) ) ) ) ) )  


Notice that SimpleXMLElement is an array and the outer-most tag <Workbook> is not an object element of the returned SimpleXMLElement. It is rather the whole object body. So we can do the following operation.
 
// Get an object element of the $Workbook and var_dump
$Worksheet = $Workbook->Worksheet;

Print out of var_dump ($Worksheet):object(SimpleXMLElement)#2 (1) { ["Table"]=> object(SimpleXMLElement)#8 (2) { ["Column"]=> array(2) { [0]=> object(SimpleXMLElement)#7 (0) { } [1]=> object(SimpleXMLElement)#6 (0) { } } ["Row"]=> array(3) { [0]=> object(SimpleXMLElement)#5 (1) { ["Cell"]=> array(3) { [0]=> object(SimpleXMLElement)#10 (1) { ["Data"]=> string(9) "Acton, MA" } [1]=> object(SimpleXMLElement)#9 (1) { ["Data"]=> string(18) "42.485819999999997" } [2]=> object(SimpleXMLElement)#12 (1) { ["Data"]=> string(19) "-71.433299000000005" } } } [1]=> object(SimpleXMLElement)#4 (1) { ["Cell"]=> array(3) { [0]=> object(SimpleXMLElement)#12 (1) { ["Data"]=> string(11) "Berkley, MA" } [1]=> object(SimpleXMLElement)#9 (1) { ["Data"]=> string(18) "41.846356999999998" } [2]=> object(SimpleXMLElement)#10 (1) { ["Data"]=> string(19) "-71.082538999999997" } } } [2]=> object(SimpleXMLElement)#11 (1) { ["Cell"]=> array(3) { [0]=> object(SimpleXMLElement)#10 (1) { ["Data"]=> string(10) "Boston, MA" } [1]=> object(SimpleXMLElement)#9 (1) { ["Data"]=> string(9) "42.358635" } [2]=> object(SimpleXMLElement)#12 (1) { ["Data"]=> string(19) "-71.056698999999995" } } } } } }
 



We will now show an example of XML use in PHP.
In the example we will use Microsoft Excel program to create excel data and store it in XML format.
We will then insert the XML data into a MySql database. This is basically creating MySql data using a spreadsheet.
 

The picture below shows the data in the spreadsheet. We need to save it in XML format.
 


 

To save Excel data in XML format select "Save As" and "Other Formats" as shown below.
 


 

Then select *.xml for "Save as type" as shown below. Give the file name as "citiesMaUsa".
And we want to organize files, so create a folder "resource" in the website folder where the ".php" files are stored.
Select the save file destination folder as "resource" folder.
And click "save".
 

 
Now we should have a file "citiesMaUsa.xml" in the folder "resource".
The data is shown below.
 

Below is the XML data in "citiesMaUsa.xml".
 
<?xml version="1.0"?> 
<?mso-application progid="Excel.Sheet"?> 
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
xmlns:o="urn:schemas-microsoft-com:office:office" 
xmlns:x="urn:schemas-microsoft-com:office:excel" 
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
xmlns:html="http://www.w3.org/TR/REC-html40"> 
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> 
<LastAuthor>Woon Yeo</LastAuthor> 
<Created>2012-07-27T01:19:32Z</Created> 
<LastSaved>2012-07-27T01:07:10Z</LastSaved> 
<Version>12.00</Version> 
</DocumentProperties> 
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"> 
<WindowHeight>8520</WindowHeight> 
<WindowWidth>17040</WindowWidth> 
<WindowTopX>240</WindowTopX> 
<WindowTopY>15</WindowTopY> 
<ProtectStructure>False</ProtectStructure> 
<ProtectWindows>False</ProtectWindows> 
</ExcelWorkbook> 
<Styles> 
<Style ss:ID="Default" ss:Name="Normal"> 
<Alignment ss:Vertical="Bottom"/> 
<Borders/> 
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/> 
<Interior/> 
<NumberFormat/> 
<Protection/> 
</Style> 
</Styles> 
<Worksheet ss:Name="maCitiesGps"> 
<Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="10" x:FullColumns="1" 
x:FullRows="1" ss:DefaultRowHeight="15"> 
<Column ss:AutoFitWidth="0" ss:Width="110.25"/> 
<Column ss:AutoFitWidth="0" ss:Width="78" ss:Span="1"/> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Acton, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.485819999999997</Data></Cell> 
<Cell><Data ss:Type="Number">-71.433299000000005</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Andover, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.653565</Data></Cell> 
<Cell><Data ss:Type="Number">-71.136493999999999</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Arlington, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.416294999999998</Data></Cell> 
<Cell><Data ss:Type="Number">-71.156763999999995</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Auburn, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.196207999999999</Data></Cell> 
<Cell><Data ss:Type="Number">-71.833922999999999</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Bedford, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.491891000000003</Data></Cell> 
<Cell><Data ss:Type="Number">-71.281470999999996</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Belmont, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.396261000000003</Data></Cell> 
<Cell><Data ss:Type="Number">-71.177012000000005</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Berkley, MA</Data></Cell> 
<Cell><Data ss:Type="Number">41.846356999999998</Data></Cell> 
<Cell><Data ss:Type="Number">-71.082538999999997</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Boston, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.358635</Data></Cell> 
<Cell><Data ss:Type="Number">-71.056698999999995</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Boxborough, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.484017000000001</Data></Cell> 
<Cell><Data ss:Type="Number">-71.514116999999999</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="0"> 
<Cell><Data ss:Type="String">Braintree, MA</Data></Cell> 
<Cell><Data ss:Type="Number">42.206391000000004</Data></Cell> 
<Cell><Data ss:Type="Number">-71.004817000000003</Data></Cell> 
</Row> 
</Table> 
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"> 
<PageSetup> 
<Header x:Margin="0.3"/> 
<Footer x:Margin="0.3"/> 
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/> 
</PageSetup> 
<Unsynced/> 
<Selected/> 
<Panes> 
<Pane> 
<Number>3</Number> 
<ActiveRow>12</ActiveRow> 
<ActiveCol>1</ActiveCol> 
</Pane> 
</Panes> 
<ProtectObjects>False</ProtectObjects> 
<ProtectScenarios>False</ProtectScenarios> 
</WorksheetOptions> 
</Worksheet> 
</Workbook>
 
Now we will use the MySql code similar to the code we saw in the previous section to store the XML data into the database.
The "xmlTest.php" file contains the code .
Run the program by issuing "http://localhost/phplab/xmlTest.php".
The code is shown below.
Start XAMPP Apache and MySql servers before running the code.
 
 
------------------------------ code start -------------------------------
<?php 
 
$GLOBALS["host"] = "localhost"; 
$GLOBALS["username"] = "root"; 
$GLOBALS["password"] = ""; 
$GLOBALS["database"] = "cities"; // data base name 
 
 
class CitiesDb { 
 
// If $rebuild == true db will be re-built. 
// 
public function initDb ($rebuild) { 
$retArr = array ( 
"STATUS" => "true", 
); 
 
$db = $GLOBALS["database"]; 
 
$dbConn = @mysql_connect ($GLOBALS["host"], $GLOBALS["username"], $GLOBALS["password"]); 
if (!$dbConn) { 
$retArr ["STATUS"] = "false"; 
$retArr ["ERROR"] = "ERROR: DB Connection" . mysql_error(); 
return $retArr; 
} else { 
if ($rebuild) { 
if (mysql_query("DROP DATABASE IF EXISTS $db", $dbConn)) 
echo "DB dropped.. " . $db; 

 
$select_db = @mysql_select_db ($db, $dbConn); 
if ($select_db) // DB exists OK 
return $retArr; 
 
echo "DB does not exist... "; 
 
if (mysql_query("CREATE DATABASE $db", $dbConn)) { 
echo "DB database created "; 
} else { 
$retArr ["STATUS"] = "false"; 
$retArr ["ERROR"] = "ERROR: DB error creating database " . mysql_error(); 
return $retArr; 

 
$select_db = @mysql_select_db ($db, $dbConn); 
if (!$select_db) { 
$retArr ["STATUS"] = "false"; 
$retArr ["ERROR"] = "ERROR: DB could not connect " . mysql_error(); 
return $retArr; 

 
$sqlStr = 
"CREATE TABLE tbl_cities ( 
id int NOT NULL AUTO_INCREMENT, 
city varchar(32) NOT NULL, 
latitude varchar(32) NOT NULL, 
longitude varchar(32) NOT NULL, 
create_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 
PRIMARY KEY (id), 
UNIQUE KEY city (city) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8"; 
$result = mysql_query ($sqlStr, $dbConn); 
if (!$result) { 
$retArr ["STATUS"] = "false"; 
$retArr ["ERROR"] = "ERROR: DB invalid query " . mysql_error(); 
return $retArr; 
} else { 
echo "DB op success "; 



 
 
// Returns affected row number (inserted recordNum). 
// 
public function insertCity ($city, $latitude, $longitude) { 
$db = $GLOBALS["database"]; 
$retArr = array ( 
"STATUS" => "true", 
); 
 
$dbConn = @mysql_connect ($GLOBALS["host"], $GLOBALS["username"], $GLOBALS["password"]); 
if (!$dbConn) { 
$retArr ["STATUS"] = "false"; 
$retArr ["ERROR"] = "ERROR: DB Connection"; 
return $retArr; 
} else { 
$select_db = @mysql_select_db ($db, $dbConn); 
if (!$select_db) { 
$retArr ["STATUS"] = "false"; 
$retArr ["ERROR"] = "ERROR: DB Select"; 
return $retArr; 

 
$tbl = "tbl_cities"; 
 
$sqlStr = // this is double quoted string, so variables will be expanded 
"INSERT INTO $tbl (city, latitude, longitude) VALUES 
('$city','$latitude','$longitude')"; 
$result = mysql_query ($sqlStr, $dbConn); 
if (!$result) { 
$retArr ["STATUS"] = "false"; 
$retArr ["ERROR"] = "ERROR: Invalid Query " . mysql_error(); 
return $retArr; 

$recordNum = mysql_insert_id (); 
$retArr ["recordNum"] = $recordNum; 
return $retArr; 


 
 
public function getAllCities () { 
$db = $GLOBALS["database"]; 
$retArr = array ( 
"STATUS" => "true", 
); 
 
$dbConn = @mysql_connect($GLOBALS["host"], $GLOBALS["username"], $GLOBALS["password"]); 
if (!$dbConn) { 
$retArr ["STATUS"] = "false"; 
$retArr ["ERROR"] = "ERROR: DB Connection"; 
return $retArr; 
} else { 
$select_db = @mysql_select_db($db, $dbConn); 
if (!$select_db) { 
$retArr ["STATUS"] = "false"; 
$retArr ["ERROR"] = "ERROR: DB Select"; 
return $retArr; 

 
$tbl = "tbl_cities"; 
 
$sqlStr = "SELECT city, latitude, longitude FROM $tbl"; 
$result = mysql_query($sqlStr, $dbConn); 
if (!$result) { 
$retArr ["STATUS"] = "false"; 
$retArr ["ERROR"] = "ERROR: Invalid Query " . mysql_error(); 
return $retArr; 
} else { 
$retArr ["queryResult"] = $result; 
return $retArr; 



 
 
 
public function insertCityDemo ($xmlData) { 
$retArr = array ( 
"STATUS" => "true", 
); 
 
$Workbook = simplexml_load_string ($xmlData); // parse XML string 
//print_r($Workbook); 
$Worksheet = $Workbook->Worksheet; 
$items = $Worksheet->Table; 
//var_dump($items); 
 
foreach ($items->Row as $item) { 
$i = 0; 
$city = (string)$item->Cell[$i++]->Data; 
$latitude = (string)$item->Cell[$i++]->Data; 
$longitude = (string)$item->Cell[$i++]->Data; 
// insert one row 
$retArr = self::insertCity ($city, $latitude, $longitude); 
if ($retArr ["STATUS"] == "false") return $retArr; 

return $retArr; 


 
?> 
 
 
&nbsp;<br><br><br> 
<!-- ----------------------- Execution Start --------------------------- --> 
&nbsp;<br><br> 
 
<?php 
// Execution Start 
 
echo "<b>------------------- From CitiesDb -----------------------</b><br>";  
echo "<br><br>";  
 
$db = new CitiesDb; 
 
//ob_start(); // if we want to capture the echo-ed outputs from the called function -- 
 
//$rebuild = false; // set false or true 
$rebuild = true; 
// if data base does not exist create one 
$retArr = $db->initDb ($rebuild); 
 
//ob_get_clean(); // -- and throw away 
 
echo "<br><br><br>"; 
 
$status = $retArr ["STATUS"]; 
if ($status == "false") { // error 
$err = $retArr ["ERROR"]; 
$resp = "<XMLDATA>"."<STATUS>false</STATUS>"."<ERROR>".$err."</ERROR>"."</XMLDATA>"; 
echo $resp; 
return; 

 
if ($rebuild) { 
$status = false; 
$dataXml = ""; 
$dataFile = "resource/citiesMaUsa.xml"; 
$fh = fopen ($dataFile, 'rb'); 
if ($fh != false) { 
$dataXml = fread($fh, filesize($dataFile)); 
if ($dataXml != false) { 
$status = true; 

fclose ($fh); 

 
if ($status == false){ 
$err = $retArr ["ERROR"]; 
$resp = "<XMLDATA>"."<STATUS>false</STATUS>"."<ERROR>".$err."</ERROR>"."</XMLDATA>"; 
echo $resp; 
return; 

 
 
// insert data using XML string 
$retArr = $db->insertCityDemo($dataXml); 
 
$status = $retArr ["STATUS"]; 
if ($status == "false") { // error 
$err = $retArr ["ERROR"]; 
$resp = "<XMLDATA>"."<STATUS>false</STATUS>"."<ERROR>".$err."</ERROR>"."</XMLDATA>"; 
echo $resp; 
return; 


 
 
// get city list 
$retArr = $db->getAllCities(); 
 
$status = $retArr ["STATUS"]; 
if ($status == "false") { // error 
$err = $retArr ["ERROR"]; 
$resp = "<XMLDATA>"."<STATUS>false</STATUS>"."<ERROR>".$err."</ERROR>"."</XMLDATA>"; 
echo $resp; 
return; 

 
// display retrieved city list 
echo "Data base created<br><br>"; 
 
echo "<table>"; 
echo "<td>City</td><td>&nbsp;&nbsp;Latitude</td><td>&nbsp;&nbsp;Longitude</td>"; 
 
$result = $retArr ["queryResult"]; 
while ($row = mysql_fetch_array($result)){ 
$city = $row['city']; 
$latitude = number_format ($row['latitude'], 6); 
$longitude = number_format ($row['longitude'], 6); 
 
echo "<tr>"; 
echo "<td>$city</td><td>&nbsp;&nbsp;$latitude</td><td>&nbsp;&nbsp;$longitude</td>"; 
echo "</tr>"; 

echo "</table>"; 
 
echo "<br><br>"; 
?>
 
------------------------------ code end -------------------------------
 
 
When successful you will get display like this.
 
                        
City            Latitude    Longitude
Acton, MA       42.485820   -71.433299
Andover, MA     42.653565   -71.136494
Arlington, MA   42.416295   -71.156764
Auburn, MA      42.196208   -71.833923
Bedford, MA     42.491891   -71.281471
Belmont, MA     42.396261   -71.177012
Berkley, MA     41.846357   -71.082539
Boston, MA      42.358635   -71.056699
Boxborough, MA  42.484017   -71.514117
Braintree, MA   42.206391   -71.004817
 
Exercise 2: Converting SimpleXMLElement object to XML string

The following code demonstrates converting SimpleXMLElement object to XML string.
The first method uses SimpleXMLElement::asXML() method and the second method uses both asXML() and DOMDocument object methods.
 
First Method:
 
$xmlElement= simplexml_load_string('<books><book><title>Travel</title></book></books>'); 
 
$xml = $xmlElement->asXML(); 
 
echo htmlentities($xml); 
var_dump ($xml);
Output ---
 
<?xml version="1.0"?> <books><book><title>Travel</title></book></books> string(72) " Travel "
 
Second Method:
 
$xmlElement= simplexml_load_string('<books><book><title>Travel</title></book></books>'); 
 
$doc = new DOMDocument(); 
$doc->formatOutput = TRUE; // make it easy to read 
$doc->loadXML($xmlElement->asXML()); 
$xml = $doc->saveXML();  
 
echo htmlentities($xml); 
var_dump ($xml);
Output ---
 
<?xml version="1.0"?> <books> <book> <title>Travel</title> </book> </books> string(84) " Travel "
 
Homework Exercise

Starting with an XML string
<books><book><title>Travel</title></book></books>
expand it to below XML by using addChild() function.
 
<books> 
<book> 
<title>Travel</title> 
<author>Author 1</author> 
</book> 
<book> 
<title>Cooking</title> 
<author>Author 2</author> 
</book> 
<book> 
<title>Health</title> 
<author>Author 3</author> 
</book> 
<book> 
<title>Movies</title> 
<author>Author 4</author> 
</book> 
<book> 
<title>Sports</title> 
<author>Author 5</author> 
</book> 
</books>
 
After you got the XML, remove two books with titles "Health" and "Movies".
Refer to the following code which removes nodes from XML objects.
 
$arr = $books->book; 
$toBeRemoved = array ('Travel','Cooking'); 
 
$count = count($arr); 
$j = 0; 
for ($i = 0; $i < $count; $i++) { 
foreach ($toBeRemoved as $delete) { 
if ($arr[$j]->title == $delete) { 
unset($arr[$j]); 
$j = $j - 1; 
}  

$j = $j + 1; 
}
 
Verify the code by displaying the XML structure.
Submit the code.