← Назад к вопросам

Расскажи про свой опыт проектирования XSD

1.0 Junior🔥 201 комментариев
#Опыт и проекты#Софт-скиллы и мотивация

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Мой опыт проектирования XSD

XSD (XML Schema Definition) — это язык для определения структуры и ограничений XML документов. За 10+ лет я работал с XSD в разных контекстах: от интеграции с банковскими системами до обмена данными между сервисами. Поделюсь практическим опытом.

Когда я использовал XSD

Контекст 1: Банковские интеграции (2015-2017)

Тогда я работал в финтех компании, которая интегрировалась с банками. Банки требовали XML формат с XSD схемой.

Проблема: Каждый банк имел свой XSD для платежей:

  • Альфа-Банк: свой формат
  • Сбербанк: другой формат
  • Промсвязьбанк: третий формат

Все содержали одинаковую информацию (сумма, получатель, цель платежа), но структура была разная.

Решение: Я спроектировал unified XSD, который содержал все поля всех банков, затем писал трансформации для каждого банка.

Контекст 2: SOAP веб-сервисы (2017-2019)

Одна из компаний где я работал использовала SOAP для API. SOAP требует WSDL (Web Service Definition Language), который использует XSD для описания типов данных.

Контекст 3: EDI (Electronic Data Interchange)

В одном проекте нужно было обмениваться счет-фактурами с другими компаниями. Они требовали XML в определенном формате с XSD.

Что такое XSD

XSD — это XML файл который описывает структуру другого XML файла.

Пример простого XML:

<?xml version="1.0"?>
<order>
  <id>12345</id>
  <customer>
    <name>John Doe</name>
    <email>john@example.com</email>
  </customer>
  <items>
    <item>
      <product_id>1</product_id>
      <quantity>2</quantity>
      <price>50.00</price>
    </item>
  </items>
  <total>100.00</total>
</order>

Соответствующая XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="order">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="id" type="xs:integer"/>
        <xs:element name="customer">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="name" type="xs:string"/>
              <xs:element name="email" type="xs:string"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="items">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="item" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="product_id" type="xs:integer"/>
                    <xs:element name="quantity" type="xs:integer"/>
                    <xs:element name="price" type="xs:decimal"/>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="total" type="xs:decimal"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

XSD определяет:

  • Какие элементы должны быть
  • Какой тип у каждого элемента
  • Сколько раз каждый элемент может появиться
  • Какие элементы обязательны

Сложный пример: Финансовый платеж

Это был один из самых сложных XSD которые я спроектировал.

Требования:

  1. Платеж может быть:

    • Юрлицо к юрлицу (B2B)
    • Физлицо к физлицу (P2P)
    • Юрлицо к физлицу (B2C)
    • Физлицо к юрлицо (C2B)
  2. Разные данные для разных типов:

    • Для юрлица: ИНН, КПП, название
    • Для физлица: ФИО, паспорт
  3. Оплата может быть:

    • По счету (account)
    • По карте (card)
    • Кошельком (wallet)
  4. Назначение платежа — текст с ограничениями (макс 140 символов)

  5. Сумма: от 10 до 100,000,000 руб

XSD структура:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <!-- Определение типа для юрлица -->
  <xs:complexType name="LegalEntity">
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="inn" type="xs:string" minLength="10" maxLength="12"/>
      <xs:element name="kpp" type="xs:string" minLength="9" maxLength="9"/>
    </xs:sequence>
  </xs:complexType>
  
  <!-- Определение типа для физлица -->
  <xs:complexType name="Individual">
    <xs:sequence>
      <xs:element name="full_name" type="xs:string"/>
      <xs:element name="passport_number" type="xs:string" minLength="10" maxLength="10"/>
      <xs:element name="passport_series" type="xs:string" minLength="4" maxLength="4"/>
    </xs:sequence>
  </xs:complexType>
  
  <!-- Данные отправителя (может быть юрлицо или физлицо) -->
  <xs:complexType name="Sender">
    <xs:choice>
      <xs:element name="legal_entity" type="LegalEntity"/>
      <xs:element name="individual" type="Individual"/>
    </xs:choice>
  </xs:complexType>
  
  <!-- Данные получателя -->
  <xs:complexType name="Recipient">
    <xs:choice>
      <xs:element name="legal_entity" type="LegalEntity"/>
      <xs:element name="individual" type="Individual"/>
    </xs:choice>
  </xs:complexType>
  
  <!-- Способ оплаты -->
  <xs:complexType name="PaymentMethod">
    <xs:choice>
      <xs:element name="account">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="account_number" type="xs:string" minLength="20" maxLength="20"/>
            <xs:element name="bank_code" type="xs:string" minLength="9" maxLength="9"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="card">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="card_number" type="xs:string" minLength="13" maxLength="19"/>
            <xs:element name="cvv" type="xs:string" minLength="3" maxLength="4"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="wallet">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="wallet_id" type="xs:string"/>
            <xs:element name="provider" type="xs:string"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:choice>
  </xs:complexType>
  
  <!-- Основной элемент платежа -->
  <xs:element name="payment">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="id" type="xs:string"/>
        <xs:element name="timestamp" type="xs:dateTime"/>
        <xs:element name="sender" type="Sender"/>
        <xs:element name="recipient" type="Recipient"/>
        <xs:element name="amount" type="xs:decimal">
          <xs:annotation>
            <xs:documentation>Amount in rubles, min 10, max 100,000,000</xs:documentation>
          </xs:annotation>
        </xs:element>
        <xs:element name="currency" type="xs:string" fixed="RUB"/>
        <xs:element name="payment_method" type="PaymentMethod"/>
        <xs:element name="purpose" type="xs:string" maxLength="140"/>
        <xs:element name="status" type="xs:string"><!-- PENDING, APPROVED, DECLINED, EXECUTED --></xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Ограничения (Constraints) которые я часто использую

Простые ограничения

<!-- Длина строки -->
<xs:element name="password" type="xs:string" minLength="8" maxLength="20"/>

<!-- Диапазон чисел -->
<xs:element name="age" type="xs:integer" minInclusive="0" maxInclusive="150"/>

<!-- Паттерн (регулярное выражение) -->
<xs:element name="email" type="xs:string">
  <xs:restriction>
    <xs:pattern value="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"/>
  </xs:restriction>
</xs:element>

<!-- Фиксированное значение -->
<xs:element name="version" type="xs:string" fixed="1.0"/>

<!-- Перечисление (enum) -->
<xs:element name="status" type="xs:string">
  <xs:restriction>
    <xs:enumeration value="PENDING"/>
    <xs:enumeration value="APPROVED"/>
    <xs:enumeration value="DECLINED"/>
  </xs:restriction>
</xs:element>

Проблемы которые я встречал при работе с XSD

Проблема 1: Эволюция XSD

Ситуация: Версия 1 XSD:

<xs:element name="order">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="customer_name" type="xs:string"/>
      <xs:element name="email" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

Потом нужно добавить номер телефона. Если я изменю XSD и сделаю его обязательным, старые XML файлы станут невалидными!

Решение: Использовать minOccurs="0" для новых элементов:

<xs:element name="phone" type="xs:string" minOccurs="0"/>

В результате:

  • Старые системы могут игнорировать новый элемент
  • Новые системы могут добавлять phone
  • Совместимость сохранена (backward compatibility)

Проблема 2: Сложность XSD

Проблема: Для сложных доменов (финансы, здравоохранение) XSD становится очень большим и сложным (1000+ строк).

Решение:

  • Разбить на несколько файлов
  • Использовать includes и imports
  • Документировать каждый элемент

Проблема 3: Валидация производительности

Проблема: При миллионах XML документов валидация по XSD становится медленной.

Решение:

  • Валидировать только критичные элементы
  • Использовать caching
  • Валидировать на клиенте если возможно

Когда XSD уже не нужен

В последние годы я заметил что XSD становится менее популярным. Причины:

  1. JSON стал популярнее

    • JSON более простой и читаемый
    • JSON Schema проще чем XSD
    • Большинство API используют JSON
  2. REST стал стандартом вместо SOAP

    • REST использует JSON, не XML
    • Меньше сложности
  3. Динамические типы

    • Python, JavaScript используют динамические типы
    • XSD слишком rigid для них

Сейчас я использую XSD редко:

  • Для EDI (Electronic Data Interchange) с старыми системами
  • Для SOAP веб-сервисов (legacy)
  • Для некоторых интеграций с банками (которые еще используют XML)

Когда я бы рекомендовал использовать XSD

  • Когда требуется strict валидация
  • Когда документ очень сложный
  • Когда нужна совместимость с legacy системами
  • Когда требуется сертификация (финансы, здравоохранение)

Лучшие практики

  1. Версионируй XSD

    <xs:schema version="1.0">...</xs:schema>
    
  2. Документируй элементы

    <xs:element name="amount">
      <xs:annotation>
        <xs:documentation>Amount in rubles, min 10</xs:documentation>
      </xs:annotation>
    </xs:element>
    
  3. Используй namespaces

    <xs:schema xmlns="http://mycompany.com/payments/v1">
    
  4. Будь консервативен при добавлении ограничений Лучше не добавлять ограничение которое сломает старые данные.

  5. Тестируй валидацию Пиши примеры XML и проверь что они валидны.

Вывод

XSD — это мощный инструмент для описания структуры XML, но:

  • Сложен для понимания
  • Медленнее JSON Schema
  • Используется все реже

В современных проектах я предпочитаю JSON Schema, OpenAPI/Swagger или GraphQL. Но XSD все еще необходим в некоторых доменах (финансы, health, EDI) и при интеграции с legacy системами.