admin blogging cor_design cor_usability design lic_virus mail manager setting web text emissiya file lotereya loyalnost_programm server automation bit24 crm integra_business integra_is integra_site planning report telefoniya users cc_n logo_c law seo speed-up arrow-down arrow-left arrow-right chat light-bulb line-chart megaphone multichannel target target2 thumbs-up handshake profit rocket social-fb social-google social-odnoklassniki social-vk arrow-stepnext arrow-stepprev content design02 pravki prodvizhenie project razrab razrab_tz test www zakaz
Интернет-агентство Smart Traffic Контакты:
Адрес: Балканская пл. д.5 (БЦ Балканский 3) оф.19 192281 Санкт-Петербург,
Телефон:+7 (812) 333-32-21, Факс: +7 (812) 333-32-21, Электронная почта: info@smartraf.ru
+7 (812) 425-68-80
ВКонтакте

Класс XmlWriter для экспорта данных в XML файл в 1С-Битрикс

21.06.2018

С версии 17.0.0 в системе появился новый класс для создания файлов XML и экспорта данных с сайта — XmlWriter.

Данный класс содержит минимальный набор функций, достаточный для формирования стандартной структуры файлов XML, а также несколько ключевых параметров, таких как: создавать новый файл или обновлять текущий, установить кодировку, создавать теги строго в нижнем регистре, формировать дополнительные отступы при обновлении файла. Интересно будет следить за направлением расширения его функционала, поскольку считаю, что развивать и совершенствовать в нём есть что. Приятным бонусом есть формат передачи параметра create_file, который позволяет адаптировать класс для пошаговой записи в файл при больших объёмах данных, что является довольно частой задачей, стоит отметить.

Среди несомненных плюсов класса XmlWriter — возможность быстро структурировать стандартный файл и записать в него информацию. При этом используя стандартный битриксовый массив данных и всего один метод для всех составляющих данных элемента: writeItem(array $item, $wrapperTag = '').

Пример использования данной функции есть в официальной документации на сайте Битрикс, поэтому, считаю, нет необходимости подробно останавливаться на ней. Отмечу лишь, что данный метод состоит из других дополнительных, которые можно также использовать отдельно в случае, если структура файла должна соответствовать определенному формату и отличается от битриксовой.

На практике всегда есть задачи, которые раскрывают все плюсы и минусы стандартного функционала системы, с которой работаешь. В одном из таких случаев мне посчастливилось столкнуться с особенностями применения стандартных методов описываемого класса. Здесь стоит рассмотреть подробнее.

Итак, первым моментом, который требовалось реализовать, была необходимость создать корневой элемент с атрибутами. Это легко можно сделать путем передачи названия тега (создаваемого элемента) вместе с его атрибутами в метод writeBeginTag, например:

writeBeginTag('Ads formatVersion="3" target="sitename.ru"');

Полный код с содержанием вышеприведенного метода выглядит следующим образом:

$export = new \Bitrix\Main\XmlWriter(array( 'file' => '/upload/adverts.xml', // относительный путь к создаваемому файлу, файл отсутствует и установлен параметр 'create_file', то он будет автоматически создан 'create_file' => true, //создавать ли файл, или продолжить запись в уже созданный. В данном случае каждый раз будет создаваться и перезаписываться новый файл 'charset' => 'UTF-8', //кодировка файла 'lowercase' => false //приводить ли все теги к нижнему регистру )); $export->openFile(); $export->writeBeginTag('Ads formatVersion="3" target="sitename.ru"'); $export->writeEndTag('Ads'); $export->closeFile();

Следующая задача — создать элемент с вложенными динамическими подэлементами с атрибутами, вида:

<Images> <Image url="http://img.test.ru/1.jpg" /> <Image url="http://img.test.ru/2.jpg" /> </Images>

Здесь можно использовать следующий цикл:
$export->writeBeginTag('Images');
foreach($exportItem['Images'] as $image)
$export->writeFullTag('Image url="'.$siteUri.$image.'"', '');
$export->writeEndTag('Images');

где:
$siteUri — домен сайта вместе с протоколом http или https,
$image — относительный путь к изображению.

Обратите внимание, что в метод мы передаём пустое значение тега вторым параметром. Это необходимо для того, чтобы наш элемент не имел вложенного содержимого, как

<Image url="http://img.test.ru/1.jpg" />вложенное содержимое</Image>

Эта особенность метода не описана в документации, но видна по исходному коду файла класса. В нём есть проверка на наличие пустого значения:

trim($value) == '' ? '<' . $code . ' />' . PHP_EOL : '<' . $code . '>' . $this->prepareValue($value) . '</' . $code . '>' . PHP_EOL

Здесь же замечаем ещё одну особенность метода writeFullTag. Если в значение $value передать спецсимволы '<', '>', '"', '\'', '&', то они будут преобразованы в соответствующие коды спецсимволов, например:

'&lt;' или '&gt;'.Затем из переменной будут очищены непечатаемые символы через регулярное выражение:

preg_replace('/[\x01-\x08\x0B-\x0C\x0E-\x1F]/', '', $value);

В целом, здорово, что в метод заложена фильтрация и очистка данных, которая важна для поддержания целостности файла. Но данные функции оказались неудобными в случае необходимости дополнительного форматирования текста. В моём случае требовалось в элемент Description передать длинный текст с форматированием через символьные данные

<![CDATA[ ]]>. Как я уже упоминала выше, угловые скобки в методе writeFullTag преобразовываются в спецсимволы, а значит необходимо искать другие пути структурировать элемент текста.

Здесь решено было использовать нестандартный подход к использованию стандартных методов класса. После использования набора методов

$export->writeBeginTag('Description'); $export->writeBeginTag($exportItem['DescriptionData']); $export->writeEndTag('Description'); элемент Description стал выглядеть следующим образом: <Description> <![CDATA[<p><strong>Описание элемента:</strong></p> <ul><li>первый пункт</li></ul>]]> </Description>

Результат стал читаемым для парсера файла, но, к сожалению, перфекционизм структуры немного пострадал. Перед закрывающим тегом

</Description> добавился отступ слева, что нарушает удобочитаемость файла и соответственно сдвигает дальше все последующие элементы с каждым вызовом данной конструкции.

Возможно, есть более элегантное решение для последнего описанного случая, но в данной статье, думаю, можно остановиться на описанном рабочем решении, продолжая с интересом исследовать и наблюдать за развитием класса XmlWriter. Поскольку, на мой взгляд, он удобен в работе и имеет все шансы стать популярным штатным инструментом для разработчиков 1С-Битрикс.

Елена Подранецкая


Оставить заявку

Ваше имя
*
Телефон
*
Email
*