Как найти и удалить недопустимые символы в XML при выгрузке из 1С 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При формировании XML-файлов для обмена данными с сайтами или другими системами программисты часто сталкиваются с ошибкой валидности файла. Одной из самых коварных причин является наличие в текстовых данных недопустимых символов, которые визуально не видны, но «ломают» структуру XML. В платформе 1С 7.7, в отличие от 8.x, отсутствует встроенная функция НайтиНедопустимыеСимволыXML, поэтому задачу очистки данных приходится решать программными методами. В этой статье мы разберем несколько эффективных способов решения этой проблемы.

Почему возникают ошибки в XML

Проанализируем ситуацию: чаще всего «мусорные» символы попадают в информационную базу 1С при копировании данных из внешних источников — почтовых клиентов (Outlook), документов Word или таблиц Excel. К таким символам относятся управляющие коды (Control Codes), такие как вертикальная табуляция, разрыв страницы или пресловутый символ SUB (код 26). Согласно спецификации XML 1.0, большинство символов с ASCII-кодами от 0 до 31 запрещены, даже если они экранированы. Исключение составляют только символы табуляции (9), перевода строки (10) и возврата каретки (13).

Способ 1. Фильтрация по «белому списку» (допустимым символам)

Рассмотрим вариант создания функции, которая проверяет каждый символ строки на соответствие заранее определенному списку разрешенных знаков. Этот метод наиболее безопасен, так как вы сами определяете, что может попасть в файл.

Разберем пример реализации такой функции:


Функция ОчиститьСтрокуДляXML(ВходнаяСтр)
    Перем Результат, Сч, ПровСимв, ВалидСимв;
    // Определяем список всех допустимых символов (буквы, цифры, знаки препинания)
    ВалидСимв = "йцукеёнгшщзхъфывапролджэячсмитьбюЙЦУКЕЁНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ1234567890-=_+*%&$#№~*“”/\|@#qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:""ZXCVBNM<>«»`()!? ±";
    
    Результат = "";
    Для Сч = 1 По СтрДлина(ВходнаяСтр) Цикл
        ПровСимв = Сред(ВходнаяСтр, Сч, 1);
        // Если символ входит в белый список или является стандартным пробелом
        Если (Найти(ВалидСимв, ПровСимв) > 0) Или (КодСимв(ПровСимв) = 32) Тогда
            Результат = Результат + ПровСимв;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Результат;
КонецФункции

Важный момент: данный метод может быть медленным на очень больших строках из-за посимвольного перебора в цикле 1С 7.7. Однако он гарантирует отсутствие любых нежелательных символов.

Способ 2. Удаление управляющих символов по ASCII-кодам

Если нам нужно сохранить специфические символы, не входящие в стандартный алфавит, но при этом очистить строку от «мусора», мы можем ориентироваться на коды символов. Выясним причину ошибки: чаще всего это символы с кодом меньше 32.

Посмотрим на алгоритм очистки на основе кодов:

  1. Проверяем каждый символ строки.
  2. Если код символа меньше 32, проверяем, не является ли он допустимым (9, 10 или 13).
  3. Если это запрещенный управляющий код — удаляем его.
  4. Дополнительно рекомендуется заменять неразрывный пробел (код 160) на обычный пробел (код 32).

Функция ФильтроватьСпецСимволы(Стр)
    Перем ОчищеннаяСтр, к, ТекКод;
    ОчищеннаяСтр = "";
    Для к = 1 По СтрДлина(Стр) Цикл
        ТекКод = КодСимв(Сред(Стр, к, 1));
        // Допускаем только: код 9 (tab), 10 (LF), 13 (CR) и все от 32 и выше
        Если (ТекКод >= 32) Или (ТекКод = 9) Или (ТекКод = 10) Или (ТекКод = 13) Тогда
            // Заменяем неразрывный пробел на обычный для стабильности
            Если ТекКод = 160 Тогда
                ОчищеннаяСтр = ОчищеннаяСтр + " ";
            Иначе
                ОчищеннаяСтр = ОчищеннаяСтр + Симв(ТекКод);
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    Возврат ОчищеннаяСтр;
КонецФункции

Способ 3. Использование регулярных выражений (VBScript.RegExp)

Проанализируем более производительный метод. Для 1С 7.7 отличным решением является использование внешнего COM-объекта VBScript.RegExp. Регулярные выражения работают значительно быстрее циклов самой платформы и позволяют удалить все лишнее одной командой.

Посмотрим, как это реализовать:


Функция RegExpОчистка(ВходнаяСтрока)
    Перем РегВыр;
    РегВыр = СоздатьОбъект("VBScript.RegExp");
    РегВыр.Global = 1;      // Искать все вхождения
    РегВыр.MultiLine = 1;   // Работать с многострочным текстом
    
    // Паттерн ищет все символы в диапазоне 0-31, исключая коды 9, 10, 13 (через инверсию)
    // А также удаляет специфические недопустимые символы выше 127, если нужно
    РегВыр.Pattern = "[^\x09\x0A\x0D\x20-\xFF]"; 
    
    Возврат РегВыр.Replace(ВходнаяСтрока, "");
КонецФункции

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

Способ 4. Использование MSXML для автоматической проверки

Если вы формируете файл не простым текстовым методом (через Текст.ДобавитьСтроку), а используете объектную модель MSXML2.DOMDocument, система может сама подсказать наличие ошибки. При попытке присвоить свойству text узла строку с недопустимым символом, возникнет исключение.

Рассмотрим пример обхода ошибки:


Попытка
    НовыйУзел.text = ЗначениеИз1С;
Исключение
    // Если произошла ошибка, значит в строке есть недопустимый символ
    НовыйУзел.text = ФильтроватьСпецСимволы(ЗначениеИз1С);
КонецПопытки;

Такой подход позволяет локализовать проблемные реквизиты прямо в процессе выгрузки и выводить сообщение пользователю о том, в каком именно объекте (например, в наименовании номенклатуры) содержится некорректный символ.

Дополнительные рекомендации

При работе с XML в 1С 7.7 также важно помнить про стандартное «экранирование» специальных символов разметки. Даже если символ допустим, он должен быть правильно представлен:

Использование секций <![CDATA[ ... ]]> помогает избежать проблем с символами разметки (кавычками и скобками), но не защищает от запрещенных управляющих кодов (0-31). Поэтому предварительная очистка данных, рассмотренная в этой статье, является обязательным этапом для создания надежного механизма обмена.

← На главную