Почему XSD-схема не принимает регулярное выражение и как исправить ошибку проверки XML-файла

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

При выгрузке данных в формат 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. Выясним причину этого поведения.

Ключевые отличия регулярных выражений в XSD

Главная ошибка кроется в том, что автор схемы скопировал регулярное выражение из веб-разработки (например, из 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 '\-'.

Как исправить регулярное выражение для XSD-схемы

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

  1. Удалите внешние слэши и модификатор кодировки. Избавьтесь от / в начале и /u в конце строки.
  2. Удалите символы привязки к строке. Уберите символ ^ в начале и символ $ в конце выражения.
  3. Правильно оформите дефис. У вас есть два пути работы с дефисом внутри квадратных скобок:
    • Экранировать его с помощью обратного слэша: \-.
    • Переместить его в самый конец или самое начало символьного класса (например, поставить сразу после открывающей квадратной скобки или прямо перед закрывающей). В этих позициях дефис теряет роль оператора диапазона и распознается как обычный текстовый символ.
  4. Точка внутри квадратных скобок. Обратите внимание, что внутри квадратных скобок [...] точка . теряет свое значение "любого символа" и воспринимается как обычная точка. Экранировать её как \. не обязательно, но допустимо.

Примеры правильного написания шаблона

Рассмотрим, как должна выглядеть валидная 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) и любые веб-валидаторы схем.

Особенности проверки в 1С при работе с XDTO

Если вы выполняете проверку заполнения XML-файлов программно внутри платформы 1С с использованием механизмов XDTO, учитывайте следующие нюансы:

Таким образом, своевременное приведение регулярных выражений в соответствие со спецификацией W3C XML Schema избавит вас от ошибок совместимости при обмене данными между 1С и внешними информационными системами.

← На главную