diff --git a/__data__/smev-message-exchange-basic-1.1.xsd b/__data__/smev-message-exchange-basic-1.1.xsd
new file mode 100644
index 0000000..33fa907
--- /dev/null
+++ b/__data__/smev-message-exchange-basic-1.1.xsd
@@ -0,0 +1,380 @@
+
+
+
+ Базовые типы.
+
+
+
+
+
+
+
+
+ Содержательная часть сообщения СМЭВ.
+
+
+
+ Корневой элемент XML-документа запроса присоединять сюда.
+
+
+
+
+
+
+
+ Заголовки файлов, приложенных к СМЭВ-сообщению.
+ Заголовки отделены от содержимого вложений.
+ Это нужно потому, что заголовки должны попадать под ЭП-ОВ,
+ а содержимое - должно не попадать (иначе не будет работать MTOM).
+
+
+
+
+
+
+
+
+
+
+
+ Файл, приложенный к СМЭВ-сообщению.
+ Имя файла не передаётся; вложения идентифицируются только идентификаторами внутри сообщения.
+
+
+
+
+
+
+ Идентификатор вложения. Ссылка на соответствующий //AttachmentContent/@Id
+
+
+
+
+ Тип контента.
+
+
+ ЭЦП в формате PKCS#7 detached. Подписывать ключом ЭП-СП.
+
+
+
+
+
+
+ Cодержимое вложенных файлов.
+ У элемента списка, тип base64Binary и наличие атрибута expectedContentTypes - подсказка для frameworks типа JAX-WS передавать содержимое этого элемента по MTOM протоколу.
+ Кроме того, значение expectedContentTypes="application/octet-stream" - подсказка JAX-WS дать доступ к этому элементу через InputStream/OutputStream.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Идентификатор файла. Ссылка на соответствующий файл.
+
+
+
+
+ Пользователь.
+
+
+ Пароль.
+
+
+ Имя файла.
+
+
+
+
+
+
+ Содержимое вложенного файла.
+ Значение атрибута attachmentId должно быть уникально среди всех элементов и атрибутов СМЭВ-сообщения, имеющих тип xs:ID.
+
+
+
+
+
+
+
+
+
+
+ Заголовки файлов, приложенных к СМЭВ-сообщению.
+ Заголовки отделены от содержимого вложений.
+ Это нужно потому, что заголовки должны попадать под ЭП-ОВ,
+ а содержимое - должно не попадать (иначе не будет работать MTOM).
+
+
+
+
+
+
+
+
+
+
+
+ Ссылка на файл, приложенный к СМЭВ-сообщению.
+
+
+
+
+
+
+ Идентификатор файла. Ссылка на соответствующий файл.
+
+
+
+
+ Хэш файла.
+
+
+ Тип контента.
+
+
+ ЭЦП в формате PKCS#7 detached. Подписывать ключом ЭП-СП.
+
+
+
+
+
+
+ Строковое представление UUID.
+ В СМЭВ UUID используются в качестве идентификаторов сообщений.
+ Идентификаторы присваиваются сообщеням отправителями.
+
+
+
+
+
+
+
+ Тип для подписанных ссылок на сообщения СМЭВ.
+
+
+
+
+
+
+
+
+
+
+
+ Ссылка на сообщение, получение которого подтверждается методом Ack.
+ Сюда нужно писать Id СМЭВ-сообщения, который берётся
+ из //GetRequestResponse/.../SenderProvidedRequestData/MessageID/text() либо
+ из //GetResponseResponse/.../SenderProvidedRequestData/MessageID/text().
+
+
+
+
+
+
+
+
+
+ true, если ЭП-СМЭВ прошла валидацию и сообщение передано ИС. false, если ЭП-СМЭВ отвергнута, и сообщение проигнорировано.
+
+
+
+
+
+
+
+
+
+
+ Элекронная подпись в формате XMLDSig.
+
+
+
+
+
+
+ Собственно подпись, по спецификации XMLDSig.
+ Объявлена как any для того, чтобы инструменты типа JAXB не генерировали классов для пространства имён
+ http://www.w3.org/2000/09/xmldsig#.
+ Это, в свою очередь, нужно потому, что инструменты, генерирующие и проверяющие ЭЦП (напр. Apache Santuario)
+ работают с DOM-деревьями, а не с JAXB-объектами.
+
+
+
+
+
+
+ Типы вложений, в формате RFC-2046.
+
+
+
+
+
+
+
+
+ Селектор, с помощью которого при приёме запроса или ответа
+ можно задать фильтр по типу запроса (ответа).
+ Поскольку тип запроса или ответа однозначно определяется полным именем
+ корневого XML-элемента его бизнес-данных,
+ селектор представляет из себя структуру для задания этого имени.
+ Если селектор пуст, это значит, что нужно принять запрос (ответ)
+ без фильтрации по типам.
+
+
+
+
+
+
+
+
+ Текущая дата и время.
+
+
+
+
+ Идентификатор нода.
+
+
+
+
+
+
+
+
+
+
+ Запрос с таким Id не найден в БД СМЭВ.
+
+
+ Запрос находится в очереди на асинхронную валидацию.
+
+
+ Запрос доставляется поставщику.
+
+
+ Запрос не прошёл асинхронную валидацию.
+
+
+ Обрабатывается поставщиком сервиса.
+
+
+ Запрос выполнен или отвергнут поставщиком сервиса; ответ находится в очереди СМЭВ.
+
+
+ Запрос отменён потребителем сервиса.
+
+
+ Ответ получен потребителем сервиса.
+
+
+
+
+ Тип взаимодействия
+
+
+ Взаимодействие портала государственных и/или муниципальных услуг с органом власти.
+
+
+ Взаимодействие между органами власти.
+
+
+ Взаимодействие между различными информационными системами одного органа исполнительной власти через СМЭВ.
+
+
+ Взаимодействие информационно-платежного шлюза с поставщиками начислений для оплаты услуг в электронном виде.
+
+
+ Взаимодействие информационно-платежного шлюза с системой УНИФО ФК для получения начислений и фактов оплаты для пользователей ПГУ.
+
+
+ Взаимодействие ОИВ с системой УНИФО ФК для передачи начислений и получения фактов оплаты.
+
+
+ Другие типы взаимодействия.
+
+
+ Не удалось определить тип взаимодействия.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Тип элемента, который передаёт информацию фактом своего наличия.
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/__data__/smev-message-exchange-types-1.1.xsd b/__data__/smev-message-exchange-types-1.1.xsd
new file mode 100644
index 0000000..9605ae9
--- /dev/null
+++ b/__data__/smev-message-exchange-types-1.1.xsd
@@ -0,0 +1,697 @@
+
+
+
+
+ Типы и элементы для веб-сервиса, который СМЭВ предоставляет всем участникам межведомственного взаимодействия для обмена сообщениями.
+
+
+
+
+
+
+
+
+
+
+ Параметры метода "Послать запрос".
+
+
+
+ Содержательная часть запроса + служебные данные, заполняемые отправителем.
+
+
+ Вложенные файлы - содержимое. Содержимое вынесено из-под ЭП-ОВ, чтобы не нарушать работу MTOM.
+
+
+
+
+ ЭП-ОВ или ЭП-ПГУ. Подписан элемент //SenderProvidedRequestData.
+ Подпись оставлена необязательной, чтобы клиентов можно было тестировать с упрощёнными эмуляторами СМЭВ.
+ Реальный СМЭВ отбивает сообщения без ЭП-ОВ или ЭП-ПГУ.
+
+
+
+
+
+
+
+
+
+ Возвращаемое значение метода "Послать запрос": запрос принят.
+ Если запрос не может быть принят, информация о причине отказа передаётся через SOAP fault, см. WSDL-описание сервиса.
+
+
+
+
+
+
+
+ Данные о сообщении: ID, присвоенный СМЭВ, дата приёма по часам СМЭВ, результат маршрутизации, etc.
+
+
+
+
+
+
+ ЭП-СМЭВ. Подписан элемент //MessageMetadata.
+ Подпись оставлена необязательной, чтобы клиентов можно было тестировать с упрощёнными эмуляторами СМЭВ.
+
+
+
+
+
+
+
+ Параметры метода "Послать ответ на запрос".
+
+
+
+
+
+ ЭП-ОВ или ЭП-ПГУ. Подписан элемент //SenderProvidedResponseData.
+
+
+
+
+
+
+
+ Возвращаемое значение метода "Послать ответ на запрос": ответ принят.
+ Если ответ не может быть принят, информация о причине отказа передаётся через SOAP fault, см. WSDL-описание сервиса.
+
+
+
+
+
+
+
+ Данные о сообщении: ID, присвоенный СМЭВ, дата приёма по часам СМЭВ, результат маршрутизации, etc.
+
+
+
+
+
+
+ ЭП-СМЭВ. Подписан элемент //MessageMetadata.
+ Подпись оставлена необязательной, чтобы клиентов можно было тестировать с упрощёнными эмуляторами СМЭВ.
+
+
+
+
+
+
+
+
+
+ Параметры метода "получить сообщение из моей входящей очереди запросов, если очередь не пуста".
+ Какую входящую очередь смотреть - определаятся по владельцу сертификата, входящего в состав ЭЦП,
+ и селектору типа запроса.
+
+
+
+
+
+
+
+
+ ЭП-ОВ или ЭП-ПГУ. Подписан элемент //Id.
+
+
+
+
+
+
+
+
+
+ Возвращаемая структура метода "получить сообщение из моей входящей очереди запросов, если очередь не пуста".
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Сообщение об статусе асинхронной обработки в СМЭВ.
+
+
+
+
+
+
+
+
+ ЭП-СМЭВ. Подписан элемент preceding-sibling:
+
+
+
+
+
+
+
+ Параметры метода "получить сообщение из моей входящей очереди запросов, если очередь не пуста".
+ Какую входящую очередь смотреть - определаятся по владельцу сертификата, входящего в состав ЭЦП,
+ и селектору типа запроса.
+
+
+
+
+
+
+
+ См. описание {urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1}MessageTypeSelector
+
+
+
+
+
+
+ ЭП-ОВ или ЭП-ПГУ. Подписан элемент //MessageTypeSelector.
+
+
+
+
+
+
+
+
+
+ Параметры метода "получить сообщение из моей входящей очереди ответов, если очередь не пуста".
+ Какую входящую очередь смотреть - определаятся по владельцу сертификата, входящего в состав ЭЦП,
+ и селектору типа _ответа_.
+
+
+
+
+
+
+
+ См. описание {urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1}MessageTypeSelector
+
+
+
+
+
+
+ ЭП-ОВ или ЭП-ПГУ. Подписан элемент //MessageTypeSelector.
+
+
+
+
+
+
+
+
+
+ Возвращаемая структура метода "получить сообщение из моей входящей очереди запросов, если очередь не пуста".
+
+
+
+
+
+
+
+ Полученное сообщение. Если этот элемент отсутствует, это значит, что входящая очередь пуста.
+
+
+
+
+
+
+
+
+
+
+
+
+ ЭП-СМЭВ. Подписан элемент //Request, либо //Cancel
+
+
+
+
+
+
+
+
+
+
+ Возвращаемая структура метода "получить сообщение из моей входящей очереди, если очередь не пуста".
+
+
+
+
+
+
+ Если у GetResponseResponse нет child element, это значит, что входящая очередь пуста.
+
+
+
+ Ответ, присланный поставщиком данных.
+
+
+
+
+
+ ЭП-СМЭВ. Подписан элемент preceding-sibling::tns:Response
+
+
+
+
+
+
+
+
+
+
+
+
+ Категория статуса.
+
+
+ Описание процессинга в человекочитаемом виде.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Параметры метода "Подтверждение получения сообщения".
+
+
+
+
+ ЭП-ОВ или ЭП-ПГУ. Подписан элемент preceding-sibling::basic:AckTargetMessage.
+
+
+
+
+
+ Возвращаемое значение метода "Подтверждение получения сообщения".
+
+
+
+
+ Параметры метода "получить статистику входящей очереди".
+ Какую входящую очередь смотреть - определаятся по владельцу сертификата, входящего в состав ЭЦП.
+
+
+
+
+
+
+
+ Идентификатор нода.
+
+
+
+
+
+
+
+ ЭП-ОВ или ЭП-ПГУ. Подписан элемент //СurrentTimestamp.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Идентификатор, присвоенный сообщению отправителем.
+ Генерируется в соответствии с RFC-4122, по варианту 1 (на основании MAC-адреса и текущего времени).
+
+
+
+
+
+
+ Идентификатор сообщения, порождающего цепочку сообщений.
+ При отправке подчиненных сообщений значение соответствует MessageID корневого сообщения цепочки сообщений.
+ Для корневого сообщения значение совпадает с MessageID
+
+
+
+
+
+
+ Идентификатор кода транзакции.
+
+
+
+
+
+
+ Идентификатор нода отправителя.
+
+
+
+
+
+
+ Ограничение жизни сообщения.
+
+
+
+
+ Содержательная часть запроса, XML-документ.
+
+
+
+
+ ЭП-СП содержательной части запроса.
+ Подписывается элемент, находящийся сразу под MessagePrimaryContent.
+ Хотя этот элемент не обязателен, поставщик данных может потребовать,
+ чтобы в запросах определённых типов ЭП-СП всегда была.
+ Это вызвано тем, что в ряде случаев, согласно ФЗ, сведения могут предоставляться только по запросам
+ должностных лиц определённого уровня.
+
+
+
+
+ Заголовки вложенных файлов.
+
+
+ Заголовки файлов по ссылке.
+
+
+
+
+ Информация о бизнес-процессе, в рамках которого пересылается данное сообщение.
+ Формат данных определяется в отдельной схеме (схемах).
+ На текущий эта информация не обязательна для заполнения отправителем.
+
+
+
+
+
+
+
+
+
+
+
+ Если этот элемент присутствует, то запрос - тестовый.
+ В этом случае, ИС-поставщик данных должна гарантировать, что её данные не будут изменены
+ в результате выполнения этого запроса.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Идентификатор, присвоенный сообщению отправителем.
+ Генерируется в соответствии с RFC-4122, по варианту 1 (на основании MAC-адреса и текущего времени).
+
+
+
+
+
+
+ Адрес доставки ответа. Копируется из запроса, //GetRequestResponse/ReplyTo/text()
+
+
+
+
+
+
+ Содержательная часть ответа, XML-документ.
+
+
+ ЭП-СП содержательной части ответа. Подписывается элемент, находящийся сразу под MessagePrimaryContent.
+
+
+ Заголовки вложенных файлов.
+
+
+ Заголовки файлов по ссылке.
+
+
+
+
+
+
+ Код причины отклонения запроса.
+
+
+ Причина отклонения запроса, в человекочитаемом виде.
+
+
+
+
+
+
+
+
+ Код бизнес статуса запроса.
+
+
+
+
+
+
+
+
+
+
+ Бизнес статус запроса, в человекочитаемом виде.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Информация об отправителе, дате отправки, маршрутизации сообщения, и другая (см. определение типа).
+ Все данные заполняются СМЭВ.
+ Элемент //MessageMetadata/SendingTimestamp содержит дату и время, начиная с которых отсчитывается срок исполнения запроса.
+ Остальные данные предназначены для целей анализа (машинного и ручного) качества обслуживания
+ информационной системы - получателя сообщения,
+ а также для предоставления службе поддержки оператора СМЭВ в случае необходимости.
+
+
+
+
+
+
+
+
+ Аналог обратного адреса; непрозрачный объект, по которому СМЭВ сможет вычислить, кому доставить ответ на этот запрос.
+ При отправке ответа нужно скопировать это значение в //SenderProvidedResponseData/To/text().
+ N.B. Формат обратного адреса не специфицирован, и может меняться со временем.
+ Больше того, в запросах, пришедших от одного и того же отправителя через сколь угодно малый промежуток времени,
+ обратный адрес не обязан быть одним и тем же.
+ Если получатель хочет идентифицировать отправителя, можно использовать либо маршрутную информацию СМЭВ
+ (//GetMessageIfAnyResponse/SMEVRoutingInfo/Sender/*), либо сертификат отправителя
+ (//GetMessageIfAnyResponse/CallerInformationSystemSignature/xmldsig:Signature/...)
+
+
+
+
+ ЭП-ОВ или ЭП-ПГУ отправителя. Подписан элемент //SenderProvidedRequestData
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Идентификатор сообщения, порождающего цепочку сообщений.
+ При отправке подчиненных сообщений значение соответствует MessageID корневого сообщения цепочки сообщений.
+ Для корневого сообщения значение совпадает с MessageID
+
+
+
+
+
+
+
+
+ ЭП-ОВ или ЭП-ПГУ отправителя. Подписан элемент //SenderProvidedResponseData
+
+
+
+
+
+
+
+
+
+
+
+ Ссылка на запрос, который нужно отменить.
+ Сюда нужно писать ID СМЭВ-сообщения, который был передан при отправке запроса в элементе
+ //SendRequestRequest/SenderProvidedRequestData/MessageID.
+
+
+
+
+
+
+ Идентификатор, присвоенный СМЭВ уведомлению об отмене.
+ Генерируется в соответствии с RFC-4122, по варианту 1 (на основании MAC-адреса и текущего времени).
+
+
+
+
+
+ ЭП-ОВ или ЭП-ПГУ отправителя. Подписан элемент //SenderProvidedCancelData
+
+
+
+
+
+
+
+ Маршрутная информация, заполняемая СМЭВ.
+
+
+
+
+ Информация об отправителе сообщения.
+
+
+
+ Мнемоника отправителя. Для машинной обработки. Вычисляется на основании данных сетрификата.
+
+
+
+
+ Наименование отправителя в форме, удобной для восприятия человеком.
+ Вычисляется на основании данных сертификата.
+ Не обязано полностью совпадать с официальным названием организации или органа власти.
+
+
+
+
+
+
+
+ Дата и время отправки сообщения в СМЭВ.
+
+
+
+
+
+
+ Получатель сообщения (вычислен маршрутизатором).
+ Для широковещательных сообщений не заполняется.
+
+
+
+
+
+ Мнемоника. Для машинной обработки.
+
+
+ Наименование в форме, удобной для восприятия человеком.
+
+
+
+
+
+ Дополнительная информация о сообщении.
+
+
+
+
+
+ Тип сообщения. Вычисляется СМЭВ на основании полного имени (qualified name) корневого XML-элемента сообщения.
+ Например, "Заявка на получение выписки из ЕГРИП".
+ Для ответов на запросы этот элемент опускается.
+
+
+
+
+ Тип взаимодействия, например, портал госуслуг - ОИВ.
+
+
+
+
+
+ Дата и время доставки сообщения, по часам СМЭВ.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/__tests__/XMLMarshaller.js b/__tests__/XMLMarshaller.js
index b4bfd3b..23b4e2e 100644
--- a/__tests__/XMLMarshaller.js
+++ b/__tests__/XMLMarshaller.js
@@ -288,6 +288,16 @@ test ('20319', async () => {
})
+test ('null', () => {
+
+ const xs = new XMLSchemata (Path.join (__dirname, '..', '__data__', 'smev-message-exchange-types-1.1.xsd'))
+
+ const xml = xs.stringify ({AckResponse: null})
+
+ expect (xml).toMatch ('ns2:AckResponse')
+
+})
+
test ('nillable', () => {
const xs = getXSSync (Path.join (__dirname, '..', '__data__', 'F9ASyncService_1.xsd'))
diff --git a/lib/XMLMarshaller.js b/lib/XMLMarshaller.js
index 80d572c..7527539 100644
--- a/lib/XMLMarshaller.js
+++ b/lib/XMLMarshaller.js
@@ -77,7 +77,7 @@ const XMLMarshaller = class {
}
- if (data [XSI_TYPE]) {
+ if (data && data [XSI_TYPE]) {
let {targetNamespace} = this.xs.getSchemaByLocalName(data [XSI_TYPE])
@@ -109,7 +109,7 @@ const XMLMarshaller = class {
const {attributes: {type}, children} = node
- if (data [XSI_TYPE]) {
+ if (data && data [XSI_TYPE]) {
let d = {}; for (let k in data) d [k] = data [k]
this.appendContent (this.schema.getType (data [XSI_TYPE]), d)
}