1С 8.3 : Ошибка преобразования данных XDTO: Текст XML содержит недопустимый символ

ИСТОЧНИК ОШИБОК:

Ситуации, когда возможно появление этой проблемы:
— Обмен в распределенной базе данных.
— Обновление конфигурации 1С.
— Импорт из внешних источников в 1С.

ПРОБЛЕМА:

{Форма.Управляемая.Форма(1000)}: Ошибка при вызове метода контекста (ПолучитьСписокНаСервере)
по причине:
Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа.
по причине:
Ошибка преобразования данных XDTO:
Запись значения свойства ‘v’:
форма: Элемент
имя: {http://v8.1c.ru/8.2/uobjects}v
по причине:
Текст XML содержит недопустимый символ в позиции 5 :
?{?{?U

ВАРИАНТЫ РЕШЕНИЯ:

&НаСервере
Перем RegExp;

&НаКлиенте
Процедура Старт(Команда)

АнализируемыйТекст = «§ | §§ «» | a86;a87;♥♦♣♠•88;75;89;a92;b34;b35;a88;58;68;U97;R52;¶§44;V16;↑↓→←W35;↔50;60; !
| ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
| АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя
| ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψω
| 0123456789
| ~!@#$%^&*(){}[]_-=+\|/*:;.<>?,№ !
| ' | © | ® | µ | «» | ¤¢€£¥ | § | ½¼¾ | ¹²³ | °±×÷؃§ µ";

ТекстРезультат = СтартНаСервере(АнализируемыйТекст);

Сообщить(""+АнализируемыйТекст+"
|"+ТекстРезультат);

КонецПроцедуры

&НаСервере
Функция СтартНаСервере(Знач Текст)

RegEXP_Инициализация();

Если RegExp = Неопределено Тогда
Value = ИсключитьНеЧитаемыеСимволыИзСтроки(Текст);                 // Вариант "НЕТИПОВОЙ 1С".
Иначе
Value = ИсключитьНеЧитаемыеСимволыИзСтроки_REGEXP(Текст);    // Вариант "НЕТИПОВОЙ RegExp".
КонецЕсли;
//Value = ЗаменитьНедопустимыеСимволыXML(Value);                           // Вариант "ТИПОВОЙ 1С".

Возврат Value;

КонецФункции

ВАРИАНТ РЕШЕНИЯ "ТИПОВОЙ 1С":

// Функция (ТИПОВАЯ 1С), оставляющая в строке только допустимые для XML символы и цифры.
//
// Возвращаемое значение:
//    Строка.
//
&НаСервере
Функция ЗаменитьНедопустимыеСимволыXML(Знач Текст, СимволЗамены = " ")

Позиция = НайтиНедопустимыеСимволыXML(Текст);
Пока Позиция > 0 Цикл
ТекущийСимвол = Сред(Текст, Позиция, 1);
Если КодСимвола(ТекущийСимвол) = 21 Тогда    // Параграф.
Текст = СтрЗаменить(Текст, ТекущийСимвол, Символ(167));
Позиция = НайтиНедопустимыеСимволыXML(Текст);
Продолжить;
КонецЕсли;
Текст = СтрЗаменить(Текст, ТекущийСимвол, СимволЗамены);
Позиция = НайтиНедопустимыеСимволыXML(Текст);
КонецЦикла;

Возврат Текст;

КонецФункции

Достоинства:
- Максимально возможное сохранение содержимого исходной строки.
Исключаются только недопустимые для XML символы.
- Самая быстрая функция.
Недостатки:
- В итоговой строке могут присутствовать нечитаемье символы ("аброказаябры").

ВАРИАНТ РЕШЕНИЯ "НЕТИПОВОЙ RegExp":

// Функция (RegExp), инициализация.
//
// Возвращаемое значение:
//    Строка.
//
&НаСервере
Функция RegEXP_Инициализация()

// Читаемые символы.
// Латиница = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
// Кирилица = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя";
// Греческие = "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψω";
// Цифры = "0123456789";
// СпециальныеСимволы = "~
!@#$%^&*(){}[]_-=+\|/*:;.<>?,№«» «;
ДвойнаяКавычка = «^»»»;
ОдинарнаяКавычка = «^'»;
АпострофОбратный = «^» + Символ(769);    // КодСимвола 769. Обратный для символа на букве «Ё».
АвторскоеПраво = «^©»;                             // КодСимвола 169. «Copyright» — латинская буква C в окружности — авторское право.
Зарезервировано = «^®»;                           // КодСимвола 174. «Registered» — латинская буква R в окружности — товарный знак.
ТоварныйЗнак = «^™»;                               // Верхний  индекс ТМ.
ШирокоеТире = «^—»;                                // КодСимвола 8212.
ДенежныеСимволы = «^¤^¢^€^£^¥»;         // Денежная единица, Цент, Евро, Фунт стерлингов, Иена или юань.
ДробныеСимволы = «^½^¼^¾»;                // Дроби: 1/2, 1/4, 3/4.
СимволыСтепени = «^¹^²^³»;                    // Степени: 1, 2, 3.
ПрочиеСимволы = «^°^±^×^÷^Ø^ƒ^µ^»+Символ(167);    // Градус, Плюс/Минус, Знак умножения, Знак деления, Диаметр, Знак функции, Микро, Параграф.

ЧитаемыеСимволы = «[«;
ЧитаемыеСимволы = ЧитаемыеСимволы + «^a-z^A-Z^а-я^А-Я^0-9^Ё^ё^Α-Ω^α-ω»;    // Латиница + Кирилица + Цифры + Греческие.
ЧитаемыеСимволы = ЧитаемыеСимволы + «^~^^!^@^#^\$^%^\^^&^\*^\(^\)^\{^\}^\[^\]^_^\-^=^\+^\\^\|^/^\*^:^;^\.^^\?^,^№^«^»^ ";    // СпециальныеСимволы.
ЧитаемыеСимволы = ЧитаемыеСимволы + ДвойнаяКавычка + ОдинарнаяКавычка + АпострофОбратный + АвторскоеПраво + Зарезервировано +ТоварныйЗнак;
ЧитаемыеСимволы = ЧитаемыеСимволы + ШирокоеТире + ДенежныеСимволы + ДробныеСимволы + СимволыСтепени + ПрочиеСимволы;
ЧитаемыеСимволы = ЧитаемыеСимволы + "]";

ПолучитьCOMОбъектREGEXP(ЧитаемыеСимволы, Ложь, Истина, Ложь);

КонецФункции

// СПАСИБО Evg-Lylyk: http://infostart.ru/public/64222/
//
&НаСервере
Процедура ПолучитьCOMОбъектREGEXP(Шаблон, ИскатьДоПервогоСовпадения = Истина, МногоСтрок = Истина, ИгнорироватьРегистр = Истина)

Если RegExp = Неопределено Тогда   // Нужна инициализация.
Попытка
RegExp = Новый COMОбъект("VBScript.RegExp");    // Создаем объект для работы с регулярными выражениями.
Исключение
RegExp = Неопределено;
Возврат;
КонецПопытки;
КонецЕсли;

// Заполняем данные.
RegExp.MultiLine = МногоСтрок;                              // Истина — текст многострочный, Ложь — одна строка.
RegExp.Global = НЕ ИскатьДоПервогоСовпадения;   // Истина — поиск по всей строке, Ложь — до первого совпадения.
RegExp.IgnoreCase = ИгнорироватьРегистр;           // Истина — игнорировать регистр строки при поиске.
RegExp.Pattern = Шаблон;                                     // Шаблон (регулярное выражение).

КонецПроцедуры

// Функция (НЕТИПОВАЯ REGEXP), оставляющая в строке только читаемые(допустимые) для XML символы и цифры.
//
// Возвращаемое значение:
//    Строка.
//
&НаСервере
Функция ИсключитьНеЧитаемыеСимволыИзСтроки_REGEXP(Знач АнализируемыйТекст, ЗаменятьСимволы = Истина, СимволЗамены = " ")

Если НЕ RegExp.Test(АнализируемыйТекст) Тогда
Возврат АнализируемыйТекст;
КонецЕсли;

// Формирование результирующей строки.
ИтоговаяСтрока = АнализируемыйТекст;

РезультатАнализаСтроки = RegExp.Execute(АнализируемыйТекст);

Для Каждого Результат ИЗ РезультатАнализаСтроки Цикл
ТекущийСимвол = Результат.Value;
Если КодСимвола(ТекущийСимвол) = 21 Тогда    // Параграф.
ИтоговаяСтрока = СтрЗаменить(ИтоговаяСтрока, ТекущийСимвол, Символ(167));
Продолжить;
КонецЕсли;
Если ЗаменятьСимволы Тогда
// Замена символа в строке.
ИтоговаяСтрока = СтрЗаменить(ИтоговаяСтрока, ТекущийСимвол, СимволЗамены);
Иначе
// Сокращение строки на символ.
ИтоговаяСтрока = СтрЗаменить(ИтоговаяСтрока, ТекущийСимвол, "");
КонецЕсли;
КонецЦикла;

Возврат ИтоговаяСтрока;

КонецФункции

Достоинства:
- Остаются только визуализируемые, понятно читаемые допустимые для XML символы.
- Сопоставима по скорости с функцией ЗаменитьНедопустимыеСимволыXML (~ 0.5%).
Недостатки:
- Отдельные, возможно, необходимые символы могут исключаться.
(необходимо дополнить переменную ЧитаемыеСимволы).

ВАРИАНТ РЕШЕНИЯ "НЕТИПОВОЙ 1С":

// Функция (НЕТИПОВАЯ 1С), оставляющая в строке только читаемые(допустимые) для XML символы и цифры.
//
// Возвращаемое значение:
//    Строка.
//
&НаСервере
Функция ИсключитьНеЧитаемыеСимволыИзСтроки(Знач АнализируемыйТекст, ЗаменятьСимволы = Истина, СимволЗамены = " ")

// Читаемые символы.
Латиница = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Кирилица = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя";
Греческие = "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψω";
Цифры = "0123456789";
СпециальныеСимволы = "~
!@#$%^&*(){}[]_-=+\|/*:;.<>?,№«» «;
ДвойнаяКавычка = «»»»;
ОдинарнаяКавычка = «‘»;
АпострофОбратный = «L9;»;           // КодСимвола 769. Обратный для символа на букве «Ё».
АвторскоеПраво = «©»;             // КодСимвола 169. «Copyright» — латинская буква C в окружности — авторское право.
Зарезервировано = «®»;           // КодСимвола 174. «Registered» — латинская буква R в окружности — товарный знак.
ТоварныйЗнак = «™»;               // Верхний  индекс ТМ.
ШирокоеТире = «—»;                // КодСимвола 8212.
ДенежныеСимволы = «¤¢€£¥»;  // Денежная единица, Цент, Евро, Фунт стерлингов, Иена или юань.
ДробныеСимволы = «½¼¾»;    // Дроби: 1/2, 1/4, 3/4.
СимволыСтепени = «¹²³»;         // Степени: 1, 2, 3
ПрочиеСимволы = «°±×÷؃µ»+Символ(167);    // Градус, Плюс/Минус, Знак умножения, Знак деления, Диаметр, Знак функции, Микро, Параграф.

ЧитаемыеСимволы = Латиница + Кирилица + Греческие + Цифры + СпециальныеСимволы + ШирокоеТире
+ ДвойнаяКавычка + ОдинарнаяКавычка + АпострофОбратный + АвторскоеПраво + Зарезервировано + ТоварныйЗнак
+ ДенежныеСимволы + ДробныеСимволы + СимволыСтепени + ПрочиеСимволы;

// Формирование результирующей строки.
ИтоговаяСтрока = «»;
Для НомерСимвола = 1 ПО СтрДлина(АнализируемыйТекст) Цикл
ТекущийСимвол = Сред(АнализируемыйТекст, НомерСимвола, 1);
// Заменяемые символы. Системный набор значений: «Символы»:
Если ТекущийСимвол = Символы.ВК ИЛИ ТекущийСимвол = Символы.ВТаб ИЛИ ТекущийСимвол = Символы.НПП
ИЛИ ТекущийСимвол = Символы.ПС ИЛИ ТекущийСимвол = Символы.ПФ ИЛИ ТекущийСимвол = Символы.Таб Тогда
ТекущийСимвол = СимволЗамены;
КонецЕсли;
Если КодСимвола(ТекущийСимвол) = 21 Тогда    // Параграф.
ТекущийСимвол = Символ(167);
КонецЕсли;
Если Найти(ЧитаемыеСимволы, ТекущийСимвол) > 0 Тогда
ИтоговаяСтрока = ИтоговаяСтрока + ТекущийСимвол;
Иначе
Если ЗаменятьСимволы Тогда
ИтоговаяСтрока = ИтоговаяСтрока + СимволЗамены;
Иначе
// Сокращение строки на символ.
КонецЕсли;
КонецЕсли;
КонецЦикла;

Возврат ИтоговаяСтрока;

КонецФункции

Достоинства:
— Остаются только визуализируемые, понятно читаемые допустимые для XML символы.
Недостатки:
— Отдельные, возможно, необходимые символы могут исключаться.
(необходимо дополнить переменную ЧитаемыеСимволы).
— Медленнее предыдущих на 30 %.

В целях недопущения искажений текста в ссылках на скачивание находится обработка с текстом функций.