SimpleXML

Learn an easy way to parse XML and output it the way you want by using the simpleXML extensions in PHP5. Murray outlines the 3 main elements of an XML document and how to replace them with your own non-template  data and how to build an array of all the tags put in the document.

SimpleXML project primer:

To the new PHP programmer, XML is quite the mysterious thing. Recently I began writing a website that uses an XML template system, so I needed to find an easy way to parse my XML, and output it the way I needed it to be outputted. With PHP4 you have to build your own XML parser that will read and output your XML. So, with that idea I decided begin to explore PHP5, because of its simpleXML extensions.

Before jumping ahead and just building my parser, I knew that I’d have to replace elements in the XML document with data from my database; after all what would be the point of using XML for a template system if you couldn’t replace elements with your own data. So, keeping that in mind I know that I’d have to load each element of my XML document into a variable then send it through my own function to replace the things I need to replace, with the correct information. Now, let’s get started.

The first thing we should look at is the XML document. This is a simpler version of mine, but it’s still the same basic idea. Save the following as template.xml.

<?xml version=”1.0″ encoding=”UTF-8″ ?>
<template>
  <header>
<![CDATA[
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="
http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title><!title></title>
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
 <tr>
   <td style="text-align:center;"><!logo></td>
 </tr>
</table>
  ]]>
  </header>
  <body>
<![CDATA[
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
 <td width=”15%”><!column1></td>
 <td width=”70%”><!column2></td>
 <td width=”15%”><!column3></td>
</tr>
</table>
  ]]>
  </body>
  <footer>
<![CDATA[
<table width="100%" border="0" cellspacing="0" cellpadding="0">
 <tr>
  <td style="text-align:center;"><!footer></td>
 </tr>
</table>
</body></html>
  ]]>
  </footer>
</template>

{mospagebreak title=Replace Tags with Our Data}

Let’s play tag:

As you can see the XML document contains three main elements, header, body, and footer. With in each of those we have the basic three column page layout, and a few proprietary tags such as <!title> and <!logo>. These are going to be the elements that we’re going to replace with our own non-template data. So first things first, we need to figure out how to replace the tags with our data. I created the following function to do so.

function replace($load,$string,$mask='<!-tag->’){
        if(!is_array($load)){
            return $string;
        }else{
            if(!strpos($load,’-tag-‘)) $mask='<!-tag->';
            $masks=explode(‘-tag-‘,$mask);
            $tags=array_keys($load);
            foreach($tags as $tag){ 
                $newtags[]=$masks[0].$tag.$masks[1];
            }
            $loads=array_values($load);
            return str_replace($newtags,$loads,$string);
        }
    }

Before we go any farther, lets take a look at this function so you know exactly what it does.

First we define the function and all the parameters it will accept:

  • $load is the array of tags we’re going to replace, the array should be set up like this array(‘tagname’=>”data to place where the tag is”)
  • $string is the variable that holds the XML string that we’ll later get from simpleXML
  • $mask is an optional variable that you can use incase you want to use a different tag style, such as <*tag> function replace($load,$string,$mask='<!-tag->’){

Then we make sure that $load is an array so that we don’t get any nasty unexpected errors. If it’s not an array the function will just return the XML string without processing it

if(!is_array($load)){
            return $string;
}

If $load is an array, we first make sure that there isn’t a tag in the $load named “-tag-“(1). Then we explode the $mask tag by “-tag-“ so that we have an array that has the opening and closing brackets for each tag, “<!” and  “>”(2). Now you might say “why all this stuff about the tags being explode to simply get the ‘<!’ and ’>’.” The reason behind that is so that you can change the tag style to something else like <*-tag-> if you want.

(1) if(!strpos($load,’-tag-‘)) $mask='<!-tag->';
(2) $masks=explode(‘-tag-‘,$mask);

Now we’re about to use a built-in PHP function that isn’t used too often but is very useful, array_keys(). array_keys() returns the keys of the input array as the values of the output array consider the following.

$array1 = array(‘key1’=>”value1″,’key2’=>”value2″);
$array2 = array_keys($array1);
print_r($array2);

This will output:

Array
(
    [0] => key1
    [1] => key2
)

Pretty cool and useful isn’t it.

{mospagebreak title=Build List of Tags}

Now we’ll use array_keys() to get all the names of the tags from the $load array we load that into $tags (3). Then we run the $tags array through a loop to get the value of each of the array keys (4). Now we build our new list of the actual tags to replace (this is a little easier than searching the XML document to find all the replaceable tags) (5). Now we use another built in function that’s just like array_keys() but instead of operating on the keys it operates on the values. It’s surprisingly named array_values() (6). Then we put it all together and run it through srt_replace() which with loop through the arrays that we pass to it (7). Str_replace() will return a string will all occurrences of $newtags in $string replaces with $loads respectively.

(3) $tags=array_keys($load);
(4) foreach($tags as $tag){
(5)  $newtags[]=$masks[0].$tag.$masks[1];
   }
(6) $loads=array_values($load);
(7) return str_replace($newtags,$loads,$string);

That’s about it for the replace() function. Now let’s move on to how we plan on getting the XML elements to the replace() function.

Give it a little class:

Now, for the part that you probably started reading this article for, simpleXML. SimpleXML works a lot like your average PHP class. You simply set simplexml_load_file() to the value of a variable and call a file name with it to load the XML document into the script then you use the -> operator to call each element of the XML file, such as in the following snippet that uses our template.xml.

<?
//load the template.xml file.
$template = simpleXML_load_file(template.xml);
//load the header element as a string
$header = $template->header;
//output the header element
echo $header;
?>

Go ahead and try that, then check the page source in your browser and you’ll see the exact html that’s in the header element of the template.xml file. Compare that to doing the same thing in PHP4 and you’ll understand why it’s called simpleXML. As you can see simplexml_load_file() basically loads the XML file into the $template variable and sets it up as if it’s a class and you call each element as if it were a class’s variable. Pretty simple isn’t it, hence the name simpleXML. Now that you know how simpleXML is going to help us load the xml file, we’re going to talk about how to build it all to easily load your XML template file into your script, then replace the tags, without have a bunch of the $template-> lines.

{mospagebreak title=Load the XML File and Output It}

First off you know how your own XML template file is built, so knowing what elements and tags it had won’t be a problem. Secondly it’s faster at parse time to parse a function that will loop through an array of all the elements than it is to parse multiple lines that call each of the elements alone. So what we do is make a function that will accept an array that will hold the names of all the elements, then run them through the replace() function, then output them. I actually created a class to handle the loading of the XML file, building the elements array, building the tags array, and outputting it all. Here’s what I have.

<?
class template
{
    public $xml_path; //holds the path to our template files
    public $xml_file; //holds the filename of the XML file
    public $elements; //holds the array of all our XML elements
    public $element; //temporary storage of an individual XML element
    public $load; //holds the array of all our tags
    public $tmpl_file; //holds the combined path and filename of our template file
    public $tmpf; //holds the XML file after being loaded by simpleXML
    
    function load(){
        if(isset($this->xml_path)&&isset($this->xml_file)){ //make sure that both variables are set
            $this->tmpl_file=$this->xml_path.$this->xml_file; //combine the XML path and filename to make one string
        }else{
            $this->tmpl_file=”fail/safe/path/to/your/xml_file.xml”; //if both variables aren’t set load a failsafe XML file
        }
        if(file_exists($this->tmpl_file)){ //make sure the set XML file exists
            $this->tmpf=simplexml_load_file($this->tmpl_file); //load the XML file into the variable $tmpf
        }else{
            return “Error Loading Template Data: File Not Found”; //send an error if the XML file can’t be loaded
        }
    }
    
    function parse_elem(){
            if(is_array($this->elements)){ //make sure that the elements variable is an array
                foreach ($this->elements as $elem){ //loop through each element
                    $this->element=$this->tmpf->$elem; //set current element as the value of $element
                    if($this->element!=””){ //check to make sure the element isn’t empty
                        $page.=$this->replace($this->load,$this->element); //add the output of the replace function to our output variable
                    }else{
                        $page.=”Error Loading Template Data: Element “$elem” Not Valid<br />”; //add an error incase the element is invalid
                    }    
                }
            }else{
                return “Error Loading Template Data: Element Data Not Valid<br />”;//send an error if the elements variable isn’t an array
            }
            return $page; //output the final product of our hard work
    }
    
    function add_elem($key,$value){//add an element to the elements array
        if(isset($key)&&isset($value)){//make sure all information is specified
            $this->elements[$key]=$value;//add a key to the elements array containing specified data
        }else{
            echo “Error Adding Element: Element Data Missing”;//send an error incase the correct information isn’t specified
        }
    }

    function add_tags($key,$value){//add a tag to the load array
        if(isset($key)&&isset($value)){//make sure all information is specified
            $this->load[$key]=$value; //add a key to the load array containing specified data
        }else{
            //echo “Error Adding Tag: Tag Data Missing”; //send an error incase the correct information isn’t specified
        }
    }
    
    function replace($load,$string,$mask='<!-tag->’){
        if(!is_array($load)){ //make sure load variable is an array
            return $string;// if load variable isn’t an array return the string unprocessed
        }else{
            if(!strpos($load,’-tag-‘)) $mask='<!-tag->';//make sure the tag mask isn’t in the load array
            $masks=explode(‘-tag-‘,$mask);//explode the mask array to reveal tag beginning and end
            $tags=array_keys($load);//load the keys from load array into another array called $tags
            foreach($tags as $tag){ //loop through tags array
                $newtags[]=$masks[0].$tag.$masks[1];//build array of the tags for the specified data
            }
            $loads=array_values($load);//load values from load array into a separate array named $loads
            return str_replace($newtags,$loads,$string);//process all tags, replace data and the specified XML string through str_replace()
        }
    }
}
?>

It’s not actually all that complicated if you just take a second to look at it. Now, to put this all into use. Save the class that I just showed you as parser.php.

{mospagebreak title=Putting it All to Use}

That’s a wrap, err, a parse and an echo, then a wrap:

Now we need to use all this for something worthwhile. First we’ll need to set up our elements array for the parser. for this we’ll use the add_elem() function we just made in our class.

$template = new template();
$template->add_elem(“header”,”header”);
$template->add_elem(“body”,”body”);
$template->add_elem(“footer”,”footer”);

as you can see all you do is call the function an pass the names of each element to it, that will build an array in out class called $elements. Personally I just use the name of the element as the array key; it’s just less confusing for me if I need to debug anything in my site. Now we need to build the array of all the tags that we put in our XML document. We’ll use our add_tags() function for that. It works like the add_elem() does, only with a slight difference.

$template->add_tags(“title”,”This is the simpleXML test page”);
$template->add_tags(“logo”,”simpleXML is simple!”);
$template->add_tags(“column1″,”This is column one”);
$template->add_tags(“column2″,”This is column two”);
$template->add_tags(“column3″,”This is column three”);
$template->add_tags(“footer”,”this is the footer information”);

As you can see here, you name the key the same thing that the tag is going to be named, while the value of the key is the information you want to the tag to be replaced by. The value can contain anything it can be a function that has been loaded into a variable ( $var=function()), it can be a number, text, html, more php, anything, as long as it can be outputted to a browser.

After we’ve built our arrays of elements and tags, we’ll have to set our file path and filename that’s pretty easy and painless as well.

$template->xml_path = “path/to/xmlfile/”;
$template->xml_file=”template.xml”;

If the XML file is in the same directory as the index page, then you’ll still need to set the xml_path due to the error checking,  but you can set is to a blank.

$template->xml_path=””;

That’s almost all that’s left to do now all we have to do is call our function to load the XML file and the function that will output it all to the browser and that’s about it!

$template->load();
echo $template->parse_elem();

That’s it, pretty painless. As you can see the entire contents of all 3 files is less than the contents of most PHP4 version XML parsers, and this has a lot more functionality. This script can be expanded to do a lot more than it does here, in fact I encourage you to expand the script to do amazing things. I know that this script can be expanded to do a lot more than it does as it’s presented in this article because I use the exact same script expanded to do many more things. For example I set up the 3 columns as separate XML elements so that I can add flexibility to my layouts. I haven’t covered all the things you can do with simpleXML in this article, so I also encourage you to check out the rest of the functions that simpleXML offers and play around with them. Who knows what cool things you can actually do with it, because as every PHP developer knows, you can do anything you can imagine with PHP.

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye