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

У битрикс есть класс \Bitrix\Main\XmlWriter
с помощью \Bitrix\Main\XmlWriter::writeBeginTag мы начинаем тег, а
\Bitrix\Main\XmlWriter::writeEndTagзаканчивам. Можно это заменить на \Bitrix\Main\XmlWriter::writeFullTag это все понятно.

Получаю

<offers>
<offer> 
<id>1111</id>
<code>wwww</code>
<name>
Товар 1
</name>
</offer>
</offers>


Но как мне получить что то типа

<offers>
<offer id="1111' code='wwww'> // тут дописываем атрибут к тегу и вкладываем данные
<name>
Детский шестиугольный манеж ROBA с бампером Adam & Owl, белый 0232WV148
</name>
</offer>
</offers>


Нужно добавить атибут тегу и вложить данные. Как? Кто то решал похожее?
  • Вопрос задан
  • 111 просмотров
Решения вопроса 1
vhood
@vhood
Не забывайте отмечать решения
Если это (ссылку взял из комментов в документации) и есть класс \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
    {
        $result = '';

        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
            )
        );
    }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы