При выгрузке данных в формат XML из платформы 1С предприятие часто возникает необходимость валидации полученных файлов по готовым схемам XSD (XML Schema Definition). Однако разработчики регулярно сталкиваются со странным поведением валидаторов, когда вполне стандартное и рабочее регулярное выражение (например, успешно протестированное на сайтах вроде Regex101) вызывает критическую ошибку при проверке XML-документа.
В этой статье мы подробно разберем, почему возникает ошибка [facet 'pattern'] The value is not accepted by the pattern, проанализируем ключевые отличия регулярных выражений в стандарте XSD от общепринятых диалектов программирования и рассмотрим пошаговое руководство по исправлению некорректных шаблонов.
Рассмотрим классическую ситуацию. У нас есть XML-элемент с текстовым значением:
<namettl>ASDFG ASDFG</namettl>
При валидации этого файла по схеме XSD в Notepad++ или другом XML-валидаторе программа возвращает ошибку:
ERROR: Element 'namettl': [facet 'pattern'] The value 'ASDFG ASDFG' is not accepted by the pattern '/^[A-Z-ĂÎȘȚÂ .-]+$/u'.
На первый взгляд регулярное выражение выглядит корректно. Оно призвано разрешать ввод латинских символов, пробелов, точек, дефисов и специфических румынских букв (Ă, Î, Ș, Ț, Â). Тем не менее, стандартный XML-валидатор наотрез отказывается принимать строку ASDFG ASDFG. Выясним причину этого поведения.
Главная ошибка кроется в том, что автор схемы скопировал регулярное выражение из веб-разработки (например, из PHP или JavaScript), не адаптировав его под строгие стандарты консорциума W3C для XML Schema. Разберем три критических отличия, которые ломают валидацию.
1. Использование разделителей (делимитеров) и модификаторов
В таких языках программирования, как PHP, регулярные выражения обрамляются слэшами, а в конце указываются модификаторы (например, /шаблон/u, где флаг u указывает на работу в кодировке UTF-8). В XSD-схемах разделители и флаги не поддерживаются. Если вы указываете шаблон в виде /^[A-Z...]$/u, XML-валидатор буквально понимает это так: строка обязана начинаться со слэша /, далее идти по шаблону и заканчиваться символами / и u. Естественно, строка ASDFG ASDFG этому правилу не соответствует.
2. Якоря начала и конца строки (^ и $)
В большинстве языков регулярное выражение ищет совпадение в любой части строки, поэтому разработчики используют символ ^ для обозначения начала строки и символ $ для обозначения её конца. В XSD-схемах поведение по умолчанию принципиально иное: движок валидации всегда проверяет всю строку целиком. Неявные якоря начала и конца строки уже встроены в парсер. Более того, явное использование символов ^ и $ в XSD-шаблонах является синтаксической ошибкой или воспринимается буквально как поиск текстовых символов «крышки» и «доллара».
3. Позиционирование дефиса (-) внутри символьного класса
Символ дефиса внутри квадратных скобок [...] выполняет роль оператора диапазона (например, A-Z означает диапазон от A до Z). Если дефис расположен в середине перечисления и не экранирован, валидатор пытается построить диапазон между соседними символами. В выражении [A-Z-Ă...] валидатор видит конструкцию Z-Ă и пытается построить диапазон между латинской буквой 'Z' и румынской буквой 'Ă'. Поскольку эти символы принадлежат к разным несовместимым таблицам кодировки, валидатор выдает ошибку:
InvalidRegex: Pattern Value Is Not A Valid Regular Expression. The Reported Error Was: '-' Is An Invalid Character Range. Write '\-'.
Проанализируем шаги, которые необходимо выполнить, чтобы адаптировать шаблон под стандарты XML Schema.
/ в начале и /u в конце строки.^ в начале и символ $ в конце выражения.\-.[...] точка . теряет свое значение "любого символа" и воспринимается как обычная точка. Экранировать её как \. не обязательно, но допустимо.Рассмотрим, как должна выглядеть валидная XSD-схема с исправленным регулярным выражением.
Вариант 1. С экранированием дефиса внутри символьного класса:
<xs:simpleType name="namettl">
<xs:restriction base="xs:string">
<xs:pattern value="[A-ZĂÎȘȚÂ .\-]+"/>
</xs:restriction>
</xs:simpleType>
Вариант 2. С переносом дефиса в начало символьного класса (экранирование не требуется):
<xs:simpleType name="namettl">
<xs:restriction base="xs:string">
<xs:pattern value="[-A-ZĂÎȘȚÂ .]+"/>
</xs:restriction>
</xs:simpleType>
Оба варианта будут отлично работать во всех стандартных XML-процессорах, включая Notepad++, встроенные механизмы валидации 1С (при импорте через пакеты XDTO) и любые веб-валидаторы схем.
Если вы выполняете проверку заполнения XML-файлов программно внутри платформы 1С с использованием механизмов XDTO, учитывайте следующие нюансы:
^ или $), метод Проверить() объекта XDTO-пакета может вызывать неочевидные ошибки или возвращать ложные предупреждения.Таким образом, своевременное приведение регулярных выражений в соответствие со спецификацией W3C XML Schema избавит вас от ошибок совместимости при обмене данными между 1С и внешними информационными системами.