Parsing XML using PHP

Load an XML file as data using PHP

By handling mime-types and using browser detection, CodeHelp has already shown how to export XML using a PHP script. PHP can also receive XML as input – using the XML parser:

if (!($fp=@fopen("./contactsbare.xml", "r")))
        die ("Couldn’t open XML.");
$usercount=0;
$userdata=array();
$state=”;
if (!($xml_parser = xml_parser_create()))
        die("Couldn’t create parser.");

Each XML file can have it’s own DTD or structure. The PHP file using the XML parser must be tailored to one particular structure or DTD – it will then be able to read all files that are valid under that DTD. This example will use an over-simplified contacts format for XML – you will need to adapt the details of the tags (or nodes) for your own DTD. To follow the construction of the XML parser, load the example XML file into another window using the link in the Navigation Bar. (If the file doesn’t open in a new window in your browser, right click the link and choose Open in a New Window.) Multiple contacts can be specified by repeating the CONTACT tag and the PHP file therefore needs to keep track of the number of contacts used in this example. In the above code, $usercount is set to zero ready to hold the number of contacts found. $userdata will later be filled with data for each contact and $state is used to keep track of which node the parser is dealing with for each contact.

The PHP XML parser now needs two functions to be declared, one to handle the element data and one to handle the character data within the elements. This is where you need to change the code to reflect your own XML files – change the element and attribute names. I’ll start with the Element Handler. This is in two parts, a function to detect the start of real data and a function to detect when an element comes to an end – in this case to register when more than one contact is specified. Each function is called once for each node – use a switch statement to decide what action to take depending on which node is being processed. The parser will take care of the $name and $attrib variables.

function startElementHandler ($parser,$name,$attrib){
global $usercount;
global $userdata;
global $state;

switch ($name) {
        case $name=="NAME" : {
                $userdata[$usercount]["first"] = $attrib["FIRST"];
                $userdata[$usercount]["last"] = $attrib["LAST"];
                $userdata[$usercount]["nick"] = $attrib["NICK"];
                $userdata[$usercount]["title"] = $attrib["TITLE"];
                break;
                }
        }
}

function endElementHandler ($parser,$name){
global $usercount;
global $userdata;
global $state;
$state=”;
if($name=="CONTACT") {$usercount++;}
}

The function "startElementHandler()" has been abbreviated here by removing the other case $name=="" : {} statements, the full file will be looked at later.

Next, we need the character handler:

function characterDataHandler ($parser, $data) {
global $usercount;
global $userdata;
global $state;
if (!$state) {return;}
if ($state=="COMPANY") { $userdata[$usercount]["bcompany"] = $data;}
if ($state=="GENDER") { $userdata[$usercount]["gender"] = $data;}
}

Finally, tell the parser which functions to use, read the data from the opened file and parse the contents.

xml_set_element_handler($xml_parser,"startElementHandler","endElementHandler");
xml_set_character_data_handler( $xml_parser, "characterDataHandler");

while( $data = fread($fp, 4096)){
if(!xml_parse($xml_parser, $data, feof($fp))) {
break;}}
xml_parser_free($xml_parser);

The data from the XML file is now held in $userdata and can be accessed using a standard PHP loop:

for ($i=0;$i<$usercount; $i++) {
echo "Name: ".$userdata[$i]["title"]." ".
        ucfirst($userdata[$i]["first"])." ". ucfirst($userdata[$i]["last"]);
}

 

0 I like it
0 I don't like it