PHP: Use XML Paser Functions at job with patterns

In spite of the fact that the idea of division of a code and is not new the data, she saves the urgency. Convenience is conclusive - as people changing data frequently should not have access to a code.


In PHP syntax of language is based not introduction of a code in the data and in this clause{article} we shall consider one of enough convenient ways of their division. The way will be based in language XML.


Let's consider the following problem : we have many clients, and practically each of them, wish to see on the site the guest book. Each time to change the initial text of the guest book to us already podnadoelo. And speech does not go any more that a mistake which we have found, establishing the guest book in eighteenth time it was necessary to hands to correct in on the previous seventeen sites.


The data:


To avoid a similar problem, it is necessary given to separate from a code. We would like that appearance of the guest book was stored{kept} in a separate file, dynamic given (recordings) were stored{kept} in a database, and a code in the separate catalogue.


So, we could correct quickly the admitted{allowed} mistake simple replacement of an old code on new, at it original registration would be saved.


Let's describe a pattern of the guest book with help XML as follows:



<? xml version = " 1.0" encoding = "windows-1251"?>


<guestbook>

<include url = "../top.html"/>


<! [CDATA [

<H3> the Guest book - a place for idle talk </H3>

<table width=100 % cellspacing=5> <tr> <td>

<br> <center>

]]>


<record> <! [CDATA [

<table cellpadding=7 cellspacing=0 bgcolor = * F0F8F8 width=95 %>

<tr bgcolor = * E0F0F0> <td> __ NAME __

    (<a href=mailto: __ EMAIL __> __ EMAIL __ </a>) </tr>

<tr> <td> __ COMMENT __

</td> </tr>

</table>

<br>

]]> </record>


<! [CDATA [

<br>

<center> <BR> <font face=Verdana size=2>

<A href =/add/> To add recording (Add record) </A>

</font> </center>

</td> </tr> </table>

]]>


<include url = " ../bottom.htm/>


</guestbook>


Each pattern will consist their basic section <guestbook> </guestbook> inside of which the section <records> </record> describing one recording in the guest book can be located.


Besides there can is single teg <include/>, not which place the document described with the help of property url, for example will be inserted:



<include url = " ../bottom.htm/>


The circuit of the described document is below resulted reductions:



<? xml version = " 1.0" encoding = "windows-1251"?>


<guestbook>

  <include url = "../top.html"/>

  <record>

    Body of one recording

  </record>

<include url = " ../bottom.htm/>

</guestbook>


Code:


It are necessary a little - to write the program which will transform the pattern described above in HTML the document containing both external registration, and dynamically changed{changeable} given (recordings in the guest book)


For processing a pattern we shall use XML Parser functions (http://www.php.net/manual/en/ref.xml.php). This expansion PHP gives access to functions of library Expat which author is James Clark (James Clark). Library Expat is written in language C and intended for analysis XML of documents based on events. She will not check up XML the document on mistakes and does not work with ob``ektoj model XML of the document as it is done{made} by some other libraries (for example tinyXML)


In version PHP 4.3.1 (and it is possible, as in earlier) XML Parser functions are supported by default.


Let's pass directly to a spelling of the program - obrabotchika a pattern.


First we count a pattern in a variable $xmldata:



<?

$xmldata=implode (" ", file ("template.xml"));

// The associative file - stores{keeps} the data corresponding tegam.

$TMPL=Array ();

// Processable teg

$ce = "";

/*


...


Connection to MySql server is missed


...


*/



$result=mysql_query (" SELECT * FROM guestbook_database ");


In a variable $html we will deduce{remove} result of job of our script. Right at the end we shall make simply print $html;



$html = "";


We create object obrabotchik XML the document



$xml_parser = xml_parser_create ();


We set to him options and obrabotchiki. Function startElement () will be caused, when in XML the document will meet opening teg. Function endElement () will be caused, when it it will be met closing teg. For the data (that inside tega) function characterData () xml_parser_set_option ($xml_parser, XML_OPTION_CASE_FOLDING, true) will be caused; xml_set_element_handler ($xml_parser, "startElement", "endElement"); xml_set_character_data_handler ($xml_parser, "characterData");


Let's call obrabotchik XML the document



if (! xml_parse ($xml_parser, $xmldata)) {

    $error=sprintf (" the Mistake in a pattern: %s at line %d ",

           xml_error_string (xml_get_error_code ($xml_parser)),

           xml_get_current_line_number ($xml_parser));

    die ();

}


xml_parser_free ($xml_parser);


Conclusion of the data



print $html;


Now we shall consider the basic part are three functions - obrabotchika:


* startElement ()

* endElement ()

* characterData ()


In a global variable $ce we shall remember the name processable tega, that in obrabotchike characterData () to know to what element of a file $TMPL to finish contents.



function startElement ($parser, $name, $attrs) {

    GLOBAL $ce, $TMPL, $html;


    switch ($name) {

        case "INCLUDE":

            $html. = implode (" ", @file ($attrs ["URL"]));

            break;

}

    $TMPL [$name] = " ";

    $ce = $ name;

}



function endElement ($parser, $name) {

    GLOBAL $ce, $TMPL, $result, $html;


    switch ($name) {

        case "RECORD":

            while ($D=mysql_fetch_array ($result)) {

                $t = $ TMPL ["RECORD"];

                $t=str_replace (" __ NAME __ ", $D ["name"], $t);

                $t=str_replace (" __ EMAIL __ ", $D ["email"], $t);

                $t=str_replace (" __ COMMENT __ ", $D ["comment"], $t);

                $html. = $ t;

}

            break;

}

    $ce = "";

}



function characterData ($parser, $data) {

    GLOBAL $ce, $TMPL, $html;


    switch ($ce) {

        case "RECORD":

            $TMPL [$ce.] = $data;

            break;

        default:

            $html. = $ data;

}

}


Like and all. If you have understood with " XML parser functions " I recommend to study " XSLT functions " and " DOM XML functions ". They to you will help to solve similar problems{tasks}.