Skip to content

Development

Quick XML-to-HTML Templating in PHP Using SimpleXML

While I still consider myself a code monkey, my primary work these days is writing technical documentation. Recently I was asked by a client to create a visual map for their REST-based API. The map, we decided, would have fly-out boxes that showed the API method at a glance – its name, URI endpoint, query string parameters, and other essential details. I wanted to generate these fly-outs using a template, so that if I wanted to tweak their formatting (or change it entirely), I only had to change it once.

Since the API method interface is relatively static, I didn’t need to generate it on the fly, so I created a PHP script. I could have used an XSL Transform (XSLT), but instead  I decided to use pure PHP. (I’d rather use PHP and realize I have too much power than use XSLT, and realize I don’t have enough. Plus, I love PHP. There’s no shame in sticking with what you know.)

PHP has a few options for parsing XML data. The first I found was XML Parser, but I quickly passed this over. XML Parser is great for reading in large files, as it doesn’t require parsing the entire file at once. However, this means having to read the XML file in a serial format, as opposed to the tree-based format with which most programmers are familiar. The best package I found for my purposes is SimpleXML, which mimics the tree structure of an XML file as a series of embedded objects.

To understand how Simple XML works, let’s look at our sample XML file first. My goal with the XML was to define a simple format for describing a REST-based API in a relatively static file:

<?xml encoding="utf-8" version="1.0"?>

<api>
    <method name="getSomeData">
        <endpoint>http://www.myserver.com/api/getSomeData</endpoint>
        <description>Read some data off of the server. Simple enough.</description>
        <requestMethod>GET</requestMethod>
        <httpsRequired>No</httpsRequired>
        <responseFormat>JSON</responseFormat>
        <authenticationRequired>No</authenticationRequired>
        <parameters>
            <parameter name="id">
                <description>The unique integer ID of the server-side object.</description>
                <required>Yes</required>
                <type>Integer</type>
            </parameter>
        </parameters>
    </method>
</api>

To load this file, I call simplexml_load_file(). Before calling this method, however, I call libxml_use_internal_errors(true) to enable user error handling. This enables me to check for errors manually, and create my own custom error output.

libxml_use_internal_errors(true);

$xml_obj = null;
if (!$xml_obj = simplexml_load_file("api_map.xml")) {
	$errstr = "";
	foreach (libxml_get_errors() as $error) {
		// $error is an object of type LibXMLError. Use var_dump($error) to examine properties.
		$errstr .= $error->message;
	}

	die("Error opening file: " . $errstr);
}

$xml_obj is an object that models our XML file’s hierarchical format by creating iterable and accessible objects corresponding to the names of our elements. $xml_obj itself corresponds to our file’s root element, <api>. Looping through all of the methods defined in the XML file is simple:

foreach ($xml_obj->method as $method) {
    ...
}

Within the body of our foreach loop, we can access attributes of our element $method using standard associative array syntax. We access the text content of our XML nodes by calling them as object properties. The following code prints out a simple API definition for each of the API methods defined in our XML file. Notice the use of the internal foreach loop off of the property $xml_obj->parameters->parameter to iterate through each method’s parameters:

foreach ($xml_obj->method as $method) {
?>

<h1><?php echo $method["name"]; ?></h1>

<p style="font-weight:bold;"><?php echo $method->endpoint; ?></p>

<p><?php echo $method->description; ?></p>

<p style="font-weight:bold;">Parameters</p>

<table padding:10px;">
<thead>
<th>Name</th>
<th>Data Type</th>
<th>Description</th>
</thead>
<tbody>

<?php

	foreach ($method->parameters->parameter as $param) {
?>

<tr>
<td><?php echo $param["name"]; ?></td>
<td><?php echo $param->type; ?></td>
<td><?php echo $param->description; ?></td>
</tr>

<?php
	}
?>
</tbody>
</table>
<?php
}

?>

This is a simple example with bare-bones formatting, but it should give you an idea of how you can use SimpleXML to build a simple yet powerful XML-based templating application in PHP.

Be Sociable, Share!
    The following two tabs change content below.

    One Comment (Add Yours)

    1. I was having trouble with elements having attributes. that key was coming in this way ‘@attribute’. Is there any solution for this. so that key as attributes does not come from SimpleXml Object? thanks

    Add Your Comment (Get a Gravatar)