Парсинг XML-фидов поставщиков для 1С-Битрикс
XML-фид поставщика — это структурированный файл с актуальными данными по товарам: ценами, остатками, описаниями, характеристиками. В отличие от Excel-прайса, XML предсказуем: у него есть схема, и его можно парсить надёжно. Но «предсказуем» не значит «стандартен» — каждый поставщик изобретает свой XML-формат.
Форматы XML-фидов
Встречаются несколько распространённых структур:
Простой плоский XML:
<products>
<product>
<id>12345</id>
<name>Товар А</name>
<price>1500.00</price>
<stock>10</stock>
</product>
</products>
Иерархический с категориями:
<catalog>
<categories>
<category id="1" name="Электроника"/>
</categories>
<offers>
<offer id="12345" category_id="1">
<name>Товар А</name>
<param name="Цвет">Чёрный</param>
</offer>
</offers>
</catalog>
С пространствами имён (namespace):
<feed xmlns:g="http://base.google.com/ns/1.0">
<entry>
<g:id>12345</g:id>
<g:price>1500 RUB</g:price>
</entry>
</feed>
Инструменты парсинга в PHP
SimpleXML — для небольших файлов (до 50 МБ):
$xml = simplexml_load_file($filePath);
foreach ($xml->offers->offer as $offer) {
$id = (string)$offer['id'];
$price = (float)$offer->price;
}
XMLReader — для больших файлов (сотни тысяч товаров). Читает файл как поток, не загружает в память целиком:
$reader = new XMLReader();
$reader->open($filePath);
while ($reader->read()) {
if ($reader->nodeType === XMLReader::ELEMENT && $reader->name === 'offer') {
$node = new SimpleXMLElement($reader->readOuterXml());
// обработка одного элемента
}
}
При фиде на 500 000 позиций XMLReader — единственный работающий вариант. SimpleXML при таком размере исчерпает память PHP.
XPath — для навигации по сложным структурам:
$nodes = $xml->xpath('//catalog/offers/offer[@available="true"]');
Атрибуты и вложенные параметры
Многие поставщики хранят характеристики товара как список <param> элементов:
<offer id="111">
<param name="Бренд">Samsung</param>
<param name="Гарантия">12 месяцев</param>
<param name="Цвет">Серебристый</param>
</offer>
Парсинг таких параметров:
$params = [];
foreach ($offer->param as $param) {
$name = (string)$param['name'];
$value = (string)$param;
$params[$name] = $value;
}
// $params['Бренд'] === 'Samsung'
Потом маппинг $params['Бренд'] → свойство BRAND в инфоблоке Битрикс.
Маппинг в свойства инфоблока
Свойства товара в Битрикс хранятся в таблицах b_iblock_element_property (строки и числа), b_iblock_element_prop_s{N} (оптимизированное хранение). Запись через API:
CIBlockElement::SetPropertyValueCode($elementId, 'BRAND', $params['Бренд']);
// или массово при Add/Update:
'PROPERTY_VALUES' => [
'BRAND' => $params['Бренд'],
'WARRANTY' => $params['Гарантия'],
]
Для свойств-списков (тип LIST) значение должно быть ID элемента списка. Если такого значения нет — добавить через CIBlockPropertyEnum::Add().
Синхронизация: обновление vs. полная перезагрузка
Полная перезагрузка — проще. Деактивировать всё, создать/обновить по данным фида, не найденное остаётся неактивным. Проблема: при большом каталоге (50K+ позиций) — долго и нагружает базу.
Инкрементальная синхронизация — обновлять только изменившееся. Требует сравнения с предыдущим состоянием. Подходы:
- Хэш строки данных: если
md5(serialize($currentData)) !== $savedHash— обновить. - Поле
modifiedв фиде: обновлять только если дата изменения новее.
Расписание и уведомления
Фид обрабатывается по расписанию через cron. Типовое расписание для цен и остатков — каждые 2-4 часа, для описаний и характеристик — раз в сутки.
0 */3 * * * /usr/bin/php /home/bitrix/www/local/cron/supplier_xml_import.php
После каждого запуска — запись в лог: сколько обновлено, сколько ошибок, время выполнения. При ошибке (файл недоступен, некорректный XML) — уведомление администратору.
Сроки разработки
| Вариант | Состав | Срок |
|---|---|---|
| Один поставщик, простой XML | Парсер + обновление цен/остатков | 2-3 дня |
| Сложный XML с параметрами | Маппинг характеристик в свойства | 3-5 дней |
| Система для нескольких поставщиков | Конфигурируемые маппинги, UI | 6-10 дней |







