XML и SOAP для чтения

↑ 1.4 JSON, XML и другие форматы · ← Предыдущая · → Следующая

Обязательно~5 мин чтенияУровень: junior

Зачем это аналитику и PM

Партнёр из банка или госконтура присылает не JSON, а XML в конверте SOAP. Пока тег, атрибут и пространство имён сливаются в одну простыню, в задаче теряется поле, без которого метод не вызовут.

План темы

  • теги и атрибуты
  • пространства имён
  • WSDL
  • чем SOAP отличается от REST
  • где ещё встречается

Объяснение

XML — текст из вложенных элементов. Элемент начинается тегом и заканчивается таким же тегом. SOAP — способ вызвать операцию: тело кладут в общий конверт XML. WSDL — отдельный файл, который описывает, какие операции есть и какие сообщения у них на входе. Читать конверт и читать описание контракта — разные задачи.

Как бланк с полями в рамках. Имя рамки — тег. Пометка на рамке — атрибут. Текст внутри — значение. Одинаковые на вид рамки из разных канцелярий различают штампом ведомства. Штамп здесь — пространство имён.

Теги, атрибуты, имена

Тег пишут в угловых скобках. Закрывающий повторяет имя и начинается с косой черты. Текст между ними — значение элемента. Атрибут — пара внутри открывающего тега. Одно и то же сведение команда может положить и текстом, и атрибутом. В требованиях копируют выбранный способ, не «любой».

Пространство имён не даёт двум OrderId из разных словарей слиться. Его задают адресом и часто коротким префиксом. Префикс — местное сокращение, адрес — настоящий идентификатор. Два файла с префиксом ns и разными адресами — разные словари. В задаче фиксируют адрес, не только буквы префикса.

SOAP, WSDL и где это живёт

Конверт SOAP несёт тело операции. Снаружи привычные имена Envelope и Body, но они принадлежат пространству имён SOAP, а не обычным словам. Операция внутри, в примере это CancelOrder, принадлежит уже словарю партнёра. Успех и ошибка SOAP устроены своим телом, не кодами HTTP один к одному. Каким кодом HTTP партнёр сопровождает ошибку, смотрите в его документации.

WSDL перечисляет операции, сообщения и адрес сервиса. Это не пример удачного ответа, а описание, по которому генерируют клиент. Короткий корень файла ниже только показывает, с какого тега обычно начинают чтение. Полный WSDL у партнёра длиннее, его не собирают по памяти.

Так ходят старые корпоративные шины, часть банков и государственных контуров. Новый кабинет рядом может быть JSON. В одной интеграции тогда два формата, и путать их в одном примере нельзя.

JSON REST, как его часто называютSOAP
Как выглядитОбъекты и спискиКонверт XML
Что описывает контрактЧасто OpenAPIЧасто WSDL
Имя операцииОбычно путь и метод HTTPИмя элемента в теле
ОшибкаЧасто код HTTP и JSONСвоё тело ошибки, код HTTP уточняйте

Примеры

Учебный конверт. Адреса пространств имён настоящие у SOAP и вымышленные у операции (example.com). Документ разобран как корректный XML, это не вызов живого банка.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <CancelOrder xmlns="http://example.com/orders">
      <OrderId>1042</OrderId>
    </CancelOrder>
  </soap:Body>
</soap:Envelope>

OrderId здесь текст элемента, не атрибут. Тот же номер атрибутом выглядел бы иначе, и это уже другой контракт.

Корень WSDL для узнавания файла, не рабочий контракт:

<definitions name="Orders" xmlns="http://schemas.xmlsoap.org/wsdl/"/>

Нюансы и подводные камни

  • Регистр в именах тегов значим. OrderId и orderId — разные элементы.
  • Пространство имён не видно, если смотреть только текст между тегами. В баге сохраняют и атрибуты xmlns.
  • Самозакрытый тег и пара открыть-закрыть с пустотой — оба пустые элементы. Не додумывайте значение null, пока партнёр так не написал.
  • HTML тоже размечен тегами, но это не SOAP. Конверт узнают по пространству имён и по Body, не по любым скобкам.

Практика

В конверте выше выпишите пространство имён конверта, пространство имён операции и где лежит номер заказа: текст или атрибут.

Ожидаемый результат: адрес SOAP и адрес http://example.com/orders не смешаны. Номер назван текстом элемента OrderId. Рядом пометка, что полный список операций смотрят в WSDL партнёра, а не в одном примере вызова.

Вопросы с ответами

Связано с блоком Developer

Связанные темы