Лучший способ обработать большой XML в PHP
Мне нужно проанализировать большие файлы XML в php, один из них - 6,5 МБ, и они могут быть еще больше. Расширение SimpleXML, как я прочитал, загружает весь файл в объект, что может быть не очень эффективно. По вашему опыту, что будет лучшим способом?
7 ответов
Для большого файла вы захотите использовать SAX-парсер, а не DOM-парсер.
С помощью DOM-парсера он будет читать весь файл и загружать его в дерево объектов в памяти. С парсером SAX он будет последовательно читать файл и вызывать ваши пользовательские функции обратного вызова для обработки данных (начальные теги, конечные теги, CDATA и т. Д.)
С парсером SAX вам нужно будет поддерживать свое состояние (например, в каком теге вы находитесь в данный момент), что делает его немного более сложным, но для большого файла это будет намного более эффективно с точки зрения памяти.
Мой взгляд на это:
https://github.com/prewk/XmlStreamer
Простой класс, который извлекает всех дочерних элементов в корневой элемент XML при потоковой передаче файла. Проверено на 108 МБ XML-файла с pubmed.com.
class SimpleXmlStreamer extends XmlStreamer {
public function processNode($xmlString, $elementName, $nodeIndex) {
$xml = simplexml_load_string($xmlString);
// Do something with your SimpleXML object
return true;
}
}
$streamer = new SimpleXmlStreamer("myLargeXmlFile.xml");
$streamer->parse();
При использовании DOMDocument
с большими файлами XML, не забудьте передать LIBXML_PARSEHUGE
флаг в опциях load()
метод. (То же самое относится и к другим load
методы DOMDocument
объект)
$checkDom = new \DOMDocument('1.0', 'UTF-8');
$checkDom->load($filePath, LIBXML_PARSEHUGE);
(Работает с XML-файлом 120 мес.)
SAX Parser, как рекомендует Эрик Петроэле, был бы лучше для больших файлов XML. Парсер DOM загружает весь XML-файл и позволяет вам выполнять запросы xpath - парсер SAX (Simple API for XML) будет просто читать по одной строке за раз и давать вам точки подключения для обработки.
Это действительно зависит от того, что вы хотите сделать с данными? Вам нужно все это в памяти, чтобы эффективно работать с ним?
6,5 МБ не так уж много, с точки зрения современных компьютеров. Вы могли бы, например, ini_set('memory_limit', '128M');
Однако, если ваши данные могут быть переданы в потоковом режиме, вы можете захотеть использовать синтаксический анализатор SAX. Это действительно зависит от ваших потребностей использования.
SAX-парсер - это путь. Я обнаружил, что анализ SAX может стать грязным, если вы не будете организованы.
Я использую подход, основанный на STX (Streaming Transformations for XML), для анализа больших файлов XML. Я использую методы SAX для создания объекта SimpleXML, чтобы отслеживать данные в текущем контексте (т.е. только узлы между корнем и текущим узлом). Другие функции затем используются для обработки документа SimpleXML.
Мне нужно было проанализировать большой XML-файл, в котором в каждой строке содержался элемент (дамп данных Stackru). В этом конкретном случае было достаточно прочитать файл по одной строке за раз и проанализировать каждую строку, используя SimpleXML. Для меня это было то преимущество, что не нужно было учиться чему-то новому.