Как получить XML-выгрузку на Битрикс с вложенными атрибутами?

Каким образом я могу добавить атрибут к тегу и вложить данные, аналогично данному примеру при использовании класса <code>\Bitrix\Main\XmlWriter</code>?
  • 7 апреля 2024 г. 12:19
Ответы на вопрос 2
Для создания XML-выгрузки на Битрикс с вложенными атрибутами вы можете использовать класс \Bitrix\Main\XmlWriter. Вот пример кода, который показывает, как добавить атрибут к тегу и добавить вложенные данные:

```php
use Bitrix\Main\IO\File;
use Bitrix\Main\Text\XmlWriter;

$xmlFile = new File($_SERVER['DOCUMENT_ROOT'] . '/output.xml');
$xmlWriter = new XmlWriter();
$xmlWriter->openFile($xmlFile);

$xmlWriter->startDocument();
$xmlWriter->startElement('root');

// Добавление тега с атрибутом и вложенными данными
$xmlWriter->startElement('tag');
$xmlWriter->writeAttribute('attribute', 'value');
$xmlWriter->writeRaw('Nested data');
$xmlWriter->endElement(); // закрытие тега 'tag'

$xmlWriter->endElement(); // закрытие тега 'root'
$xmlWriter->endDocument();

$xmlWriter->close();
```

Этот код создаст XML-файл с корневым элементом <root>, в котором будет вложен элемент <tag> с атрибутом 'attribute' со значением 'value' и вложенными данными 'Nested data'. После выполнения кода, XML-файл будет сохранен на сервере по указанному пути.
Если это ( ссылку взял из комментов в документации ) и есть класс \Bitrix\Main\XmlWriter , то с его помощью - никак. 

Он пишет сразу в файл, так что и регуляркой итоговый результат не пройти.

Можно залезть в него рефлексией, но в программировании это моветон и читабельность кода будет ухудшена.

Самый оптимальный вариант - наследовать этот класс, изменить несколько его функций и использовать унаследованный класс. Примерно так:
class AppXmlWriter extends XmlWriter
{
    private $file = '';
    private $charset = '';
    private $tab = 0;
    private $f = null;
    private $lowercaseTag = false;
    private $errors = array();

    // конструктор скопирован, т.к. там все private
    public function __construct(array $params)
    {
        if (isset($params['file']))
        {
            $server = \Bitrix\Main\Application::getInstance()->getContext()->getServer();
            $this->file = $server->getDocumentRoot() . trim($params['file']);
            // create new file
            if (
                isset($params['create_file']) &&
                $params['create_file'] === true &&
                is_writable($this->file)
                )
            {
                unlink($this->file);
            }
        }
        if (isset($params['charset']))
        {
            $this->charset = trim($params['charset']);
        }
        else
        {
            $this->charset = SITE_CHARSET;
        }
        if (isset($params['lowercase']) && $params['lowercase'] === true)
        {
            $this->lowercaseTag = true;
        }
        if (isset($params['tab']))
        {
            $this->tab = (int)$params['tab'];
        }
    }

    public function prepareAttributes(array $attributes): string
    {
        if (empty($attributes)) {
            return '';
        }

        $result = '';
        foreach ($attributes as $key => $value) {
            $result .= sprintf(' %s="%s"', $key, $value);
        }

        return $result;
    }

    public function writeBeginTag($code, array $attributes = [])
    {
        if (!$this->f) {
            return;
        }

        fwrite($this->f, str_repeat("\t", $this->tab) . '<' . $this->prepareTag($code) . $this->prepareAttributes($attributes) . '>' . PHP_EOL);
        $this->tab++;
    }

    public function writeFullTag($code, $value, array $attributes = [])
    {
        if (!$this->f) {
            return;
        }

        $code = $this->prepareTag($code);
        $codeAttributes = $this->prepareAttributes($attributes);
        fwrite($this->f,
            str_repeat("\t", $this->tab) .
            (
                trim($value) == ''
                ? '<' . $code . $codeAttributes . ' />' . PHP_EOL
                :   '<' . $code . $codeAttributes . '>' .
                $this->prepareValue($value) .
                '</' . $code . '>' . PHP_EOL
            )
        );
    }
}
Похожие вопросы