Парсинг YML-фидов для импорта товаров в 1С-Битрикс
YML (Yandex Market Language) — это XML-формат, который Яндекс.Маркет разработал для товарных фидов. Поставщики часто предоставляют именно YML: формат задокументирован, структура известна, данные достаточно полные. Это проще, чем парсить произвольный Excel, но своих нюансов хватает.
Структура YML-фида
YML-фид имеет стандартную структуру:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE yml_catalog SYSTEM "shops.dtd">
<yml_catalog date="2024-01-15 10:30">
<shop>
<name>Название магазина</name>
<currencies>
<currency id="RUR" rate="1"/>
</currencies>
<categories>
<category id="1">Электроника</category>
<category id="2" parentId="1">Смартфоны</category>
</categories>
<offers>
<offer id="12345" available="true">
<url>https://shop.ru/product/12345</url>
<price>29990</price>
<currencyId>RUR</currencyId>
<categoryId>2</categoryId>
<picture>https://shop.ru/img/12345.jpg</picture>
<name>Смартфон Samsung Galaxy A54</name>
<vendor>Samsung</vendor>
<vendorCode>SM-A546</vendorCode>
<description>Описание товара</description>
<param name="Цвет">Чёрный</param>
<param name="Объём памяти">128 ГБ</param>
</offer>
</offers>
</shop>
</yml_catalog>
Ключевые элементы:
-
offer id— уникальный идентификатор товара у поставщика (аналог XML_ID в Битрикс). -
available— наличие: true/false. -
categoryId— ссылка на категорию. -
param— характеристики товара (произвольное количество).
Парсинг категорий и построение дерева
Категории в YML образуют иерархию через атрибут parentId. При импорте нужно создать соответствующую структуру разделов в инфоблоке Битрикс.
Алгоритм:
- Загрузить все категории в ассоциативный массив
[id => ['name' => ..., 'parentId' => ...]]. - Рекурсивно построить дерево.
- Для каждой категории: найти раздел по
XML_ID = 'yml_cat_{id}'или создать новый. - Сохранить маппинг
[yml_id => bitrix_section_id].
$sectionId = CIBlockSection::GetList(
[],
['IBLOCK_ID' => $iblockId, 'XML_ID' => 'yml_cat_' . $cat['id']],
false,
['ID']
)->Fetch()['ID'];
if (!$sectionId) {
$bs = new CIBlockSection();
$sectionId = $bs->Add([
'IBLOCK_ID' => $iblockId,
'XML_ID' => 'yml_cat_' . $cat['id'],
'NAME' => $cat['name'],
'IBLOCK_SECTION_ID' => $parentBitrixId,
'ACTIVE' => 'Y',
]);
}
Импорт товаров (offers)
Основной цикл обработки:
foreach ($xml->shop->offers->offer as $offer) {
$xmlId = (string)$offer['id'];
$available = (string)$offer['available'] === 'true';
// Сбор параметров
$params = [];
foreach ($offer->param as $param) {
$params[(string)$param['name']] = (string)$param;
}
$fields = [
'IBLOCK_ID' => $iblockId,
'NAME' => (string)$offer->name,
'XML_ID' => $xmlId,
'ACTIVE' => $available ? 'Y' : 'N',
'IBLOCK_SECTION_ID' => $sectionMap[(string)$offer->categoryId] ?? null,
'PROPERTY_VALUES' => [
'VENDOR' => (string)$offer->vendor,
'ARTICLE' => (string)$offer->vendorCode,
// характеристики из param
],
];
// Поиск существующего товара
$existId = getElementByXmlId($xmlId, $iblockId);
$el = new CIBlockElement();
if ($existId) {
$el->Update($existId, $fields);
} else {
$el->Add($fields);
}
// Обновление цены
updatePrice($existId ?: $el->LAST_ID, (float)$offer->price);
}
Загрузка изображений
YML содержит ссылки на изображения (<picture>). Загрузка и привязка к товару:
$imageUrl = (string)$offer->picture;
$tmpFile = CFile::MakeFileArray($imageUrl); // Битрикс скачает файл
if ($tmpFile) {
$el->Update($productId, ['PREVIEW_PICTURE' => $tmpFile]);
}
Загрузка изображений — самая долгая часть импорта. При фиде на 10 000 товаров — скачивание 10 000 изображений. Оптимизация: проверять, изменилось ли изображение (по хэшу URL или содержимого), не скачивать повторно.
Различия типов офферов YML
YML поддерживает несколько типов офферов с разными обязательными полями:
| Тип | Атрибут | Особенность |
|---|---|---|
| Простой | type="simple" или без атрибута |
Все категории |
| Одежда | type="vendor.model" |
Поля vendor, model, размерная сетка |
| Книги | type="book" |
Поля author, publisher, ISBN |
| Музыка/видео | type="audiobook" |
Специфические медиа-поля |
В большинстве случаев поставщики используют простой тип. Специфические типы встречаются в нишевых каталогах.
Сроки разработки
| Вариант | Состав | Срок |
|---|---|---|
| Базовый импорт | Товары, цены, категории | 2-3 дня |
| Полный с характеристиками | Маппинг param в свойства, изображения | 4-5 дней |
| Многопоставщиковая система | UI, расписание, лог, дедупликация | 7-10 дней |







