xml file sequential read in php

Borsec
Borsec used Ask the Experts™
on
I have the following xml file:
<Table xmlns:myUtils="uniSyncDc.Logic">
  <statement>
    <update>UPDATE</update>
    <insert>INSERT INTO </insert>
    <delete />
  </statement>
...
60000 times  </statement>  <statement>
....
</Table>
I am reading this file in the following way
$docStatementsFile = new DOMDocument('1.0', 'utf-8');
            $docStatementsFile->load($fileNameWithPath);
            $statementss = $docStatementsFile->getElementsByTagName( "statement");
            foreach($statementss as $statement)
            {
                  $deletes = $statement->getElementsByTagName( CONSTANTS::DELETE);
                  $delete = utf8_decode($deletes->item(0)->nodeValue);
               $Updates = $statement->getElementsByTagName( CONSTANTS::UPDATE);
                  $update =  utf8_decode($Updates->item(0)->nodeValue);
               $insertss = $statement->getElementsByTagName( CONSTANTS::INSERT );
                  $insert = utf8_decode($insertss->item(0)->nodeValue);
in this way I am loading all the 60000 entrys in memory and I dont want this because I am using a lot of memory.
How can I read this xml file sequentially, like I read a statement from the file nd execute it, I read the next statement and execute it, and so on.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
If you want to avoid the overhead of keeping the entire DOM in memory, you might want to try SAX parser instead of DOM parser. Please see attached code for example:
<?php
my $xmlfile = "C:\\Temp\\data.xml";
$currelem = "";
$update = "";
$insert = "";
$delete = "";
function startElement($parser, $name, $attrs) 
{
    global $currelem;
    $currelem = $name;
}

function endElement($parser, $name) 
{
    global $currelem;
    global $update, $insert, $delete;
	if ($currelem == "UPDATE")
		echo "update = $update\n";
	else if ($currelem=="INSERT")
		echo "insert = $insert\n";
	else if ($currelem=="DELETE")
		echo "delete = $delete\n";
}

function parseDEFAULT($parser, $data) 
{
    global $currelem;
    global $update, $insert, $delete;
    $data = preg_replace("/^\s+/", "", $data); 
    $data = preg_replace("/\s+$/", "", $data); 

    if ($data == "")
		return;
	if ($currelem=="UPDATE")
		$update = $data;
	else if ($currelem=="INSERT")
		$insert = $data;
	else if ($currelem=="DELETE")
		$delete = $data;
#	echo "$data\n";
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_default_handler($xml_parser, 'parseDEFAULT');

if (!($fp = fopen($xmlfile, "r"))) {
    die("could not open XML input");
}


while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);

?>

Open in new window

If you are loading all the entries into memory, then you're not showing all the code. Because this code segment is re-using the variables over and over each time through the foreach loop.

But what you can do is set all the variables to "" at the top of the foreach loop so they don't get re-used if a value isn't present for each record, and then after you've set the variables use them for your UPDATE/INSERT/DELETE function before looping to the top of the foreach loop to process the next record.

You may need to show more of the code to get a better answer.

Author

Commented:
to jmatix: your code is 10 times faster than my code and is the answer to my question. But there is a small problem and I cant find it. For the next xml file
<Table xmlns:myUtils="uniSyncDc.Logic">
  <statement>
    <update>UPDATE</update>
    <insert>INSERT INTO </insert>
    <delete />
  </statement>
the result is :
delete=
update=UPDATE
insert=INSERT INTO
insert=INSERT INTO, the insert entry is written twice, can you help me with this?
Most Valuable Expert 2011
Top Expert 2016

Commented:
XML looks like the wrong technology for sending sequential commands.  There is nothing inherent in XML that keeps order - it is a markup language, not a programming language.  If you want to describe the application a little more we may be able to suggest a better way to do this work.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial