Ошибка преобразования данных XDTO: Текст XML содержит недопустимый символ
Преобразование строкового значения к допустимому для XML.
Типовое, нетиповое, RegExp.
- Описание
- Подробнее
Описание
СПРАВКА:
Аббревиатура 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): //sale.itcity.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: //sale.itcity.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 %.
В целях недопущения искажений текста в ссылках на скачивание находится обработка с текстом функций.
С уважением к сообществу МА!

