Лучший способ обработать большой 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. Для меня это было то преимущество, что не нужно было учиться чему-то новому.

Другие вопросы по тегам