СПРАВКА:
Аббревиатура XDTO (англ. XML Data Transfer Objects). XDTO является механизмом объектного моделирования данных, описываемых с помощью схемы XML.
1С: Механизм XDTO: http://v8.1c.ru/overview/xdto.htm
Аббревиатура XML (англ. eXtensible Markup Language). Расширяемый язык разметки.
1С: XML-сериализация: http://v8.1c.ru/overview/Term_000000318.htm
ИСТОЧНИК ОШИБОК:
Ситуации, когда возможно появление этой проблемы:
- Обмен в распределенной базе данных.
- Обновление конфигурации 1С.
- Импорт из внешних источников в 1С.
В частности, проблема обнаружилась при разработке обработки:
1С:Системный Администратор (WSH&WMI): //infostart.ru/public/172189/
при считывании данных из реестра Windows.
ПРОБЛЕМА:
{Форма.Управляемая.Форма(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: //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 %.
В целях недопущения искажений текста в ссылках на скачивание находится обработка с текстом функций.
С уважением к сообществу МА!