I am working with xml files with 50-150k+ entries, and about 50-100MB+ in size that change daily. All entries are unique, and have 10-15 elements per entry (id, title, etc.). I'm currently pulling the xml file into a string, using simplexml to parse it, and then looping through each entry to check for changes.
Here's the basic code...
$data = file_get_contents("test.xml");
$data = preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $data);
$xml = simplexml_load_string($data);
$item_count = count($xml->entry);
foreach (range(0, $item_count - 1, 1) as $num) {
$id = (string)$xml->entry[$num]->id;
$title = (string)$xml->entry[$num]->title;
// ... etc. ...
I'm on a VPS server (1CPU, 4GB RAM, 40GB). Without any other code, just iterating over an xml file with 70k entries, at about 80MB takes 25-30 minutes. Performance wanes over time with the CPU at 98% after a few minutes (RAM is fine). The first 30K+ entries take 10 minutes, while the second 40K take about 20 minutes.
Is there a faster, more efficient way to do this than simplexml?...Or a better method for checking large XML files that change daily? (i.e. MySQL import/queries, etc.)
I've seen suggestions to use SAX parser, but I do like the easy access to elements that simplexml provides. If I can stream the xml and save RAM, that's preferable as well.
One last note, if it helps, my current logic for checking for changes is as follows:
- Create an array of previously imported entries with the entry ID as the key and a string of entry values to check as the value
- Loop through xml file and check if the current entry id/value pair exists...
// Check if current entry is in array
if ($previously_imported_entries[$id] === $value1 . " ---- " . $value2 . " --- " . $value3) {
// Item is in array, and values are the same
// No changes
// etc...
} else {
// Item isn't in the array or values have changed
// Import entry either way
}