Войти

АЛГОРИТМ трансформации XML

При подписании XML-фрагментов ЭП в формате XMLDSig, обязательно использование трансформации urn://smev-gov-ru/xmldsig/transform. Пример XML до и после трансформации по описанному ниже алгоритму приведены в Приложении Б.

Внимание! Алгоритм трансформации не применяется для графических объектов, описанных на языке идеограмм и пиктограмм (например, emoji). Перед трансформацией подобные объекты необходимо исключить из сообщения.

Алгоритм трансформации включает следующие шаги:

1.     Удаления элементов XML declaration и processing instructions (при наличии)

вход:

выход:

2.     Удаление текстовых блоков (элементов XML), содержащих только пробельные символы. Если текстовый блок содержит только пробельные символы – u0009 - табуляция, u000A – перевод строки (Unix), u000D - возврат каретки, u0020, а также любые другие символы с кодом меньшим u0020, то все пробельные символы вырезаются. В результате данного преобразования достигается отсутствие пробельных символов.

вход:

выход:

3.     После применения правил из пунктов 1 и 2, если даже у элемента нет дочерних узлов, элемент не может быть представлен в виде empty element tag (http://www.w3.org/TR/2008/REC-xml-20081126/#sec-starttags, правило [44]),  выполняется преобразование элемента в пару start-tag + end-tag.

вход:

выход:

4.     Удаление namespace prefix, которые на текущем уровне объявляются, но не используются в низлежащих тегах.

вход:

выход:

5.     Проверка наличия объявления namespace текущего элемента либо в текущем элементе, либо выше по дереву. Если объявления namespase отсутствует, то объявление namespace выполняется в текущем элементе.

6.     Namespace prefix элементов и атрибутов должны быть заменены на автоматически сгенерированные. Сгенерированный префикс состоит из литерала «ns», и порядкового номера сгенерированного префикса в рамках обрабатываемого XML-фрагмента, начиная с единицы. При генерации префиксов должно устраняться их дублирование. 

вход:

выход:

вход:

выход:

7.     Атрибуты должны быть отсортированы в алфавитном порядке: сначала по namespace URI (если атрибут - в qualified form), затем – по local name. Атрибуты в unqualified form после сортировки идут после атрибутов в qualified form.

вход:

<nns:x xmlns:nns="http://a" attrB="value1" attrA="value2">
 <y xmlns="http://a">yes!</y>
</nns:x>

выход:

<ns1:x xmlns:ns1="http://a" attrA="value2" attrB="value1">
 <ns1:y>yes!</ns1:y>
</ns1:x>

8.     Объявления namespace prefix должны находиться перед атрибутами. Объявления префиксов должны быть отсортированы в порядке объявления, а именно:

  • Первым объявляется префикс пространства имён элемента, если он не был объявлен выше по дереву.
  • Дальше объявляются префиксы пространств имён атрибутов, если они требуются. Порядок этих объявлений соответствует порядку атрибутов, отсортированных в алфавитном порядке (см. п.7 текущего перечня).

вход:

<tns:PERNAMEZPRequest xmlns:markcont="urn://x-artefacts-zags-pernamezp/markertypes/4.0.0" xmlns:tns="urn://x-artefacts-zags-pernamezp/4.0.0" xmlns:fnst="urn://x-artefacts-zags-pernamezp/types/4.0.0"  xmlns:frgu="urn://x-artefacts-zags-pernamezp/frgutypes/4.0.0" markcont:ТипЗаявл="ФЛ" ЗаявлДата="2019-08-13" tns:ИдСвед="a" markcont:Заявление="15843" ДатаСвед="2018-08-13" frgu:КодУслуги="3482943">


выход (с учетом требований шагов 6, 7, 8 алгоритма трансформации):

<ns1:PERNAMEZPRequest xmlns:ns1="urn://x-artefacts-zags-pernamezp/4.0.0" xmlns:ns2="urn://x-artefacts-zags-pernamezp/frgutypes/4.0.0" xmlns:ns3="urn://x-artefacts-zags-pernamezp/markertypes/4.0.0" ns1:ИдСвед="a" ns2:КодУслуги="3482943" ns3:Заявление="15843" ns3:ТипЗаявл="ФЛ" ДатаСвед="2018-08-13" ЗаявлДата="2019-08-13">

9.     Декодирование текста, реализуемое в СМЭВ с использованием библиотеки woodstox.

В рамках декодирования текста выполняется:

  • Декодирование текстовых блоков (в элементах);
  • Декодирование атрибутов.

a.     Декодирование текстовых блоков 

При декодировании текстовых блоков выполняется:

  • Снятие экранирования символов по правилам;
  • Разделения на части блоков, содержащих блоки символьных данных CDATA;
  • Обработка блоков размером до 12 символов;
  • Обработка блоков размером от 12 символов (включительно).   

b.      Снятие экранирования 

Снятие экранирования выполняется в текстовых блоках, не содержащих блоков символьных данных по правилам, приведенным в таблице 11.

Таблица 11 - Правила снятия экранирования

Символ с экранированием

Символ после снятия экранирования

1.    

`&#xd;`

` `

2.    

`&#13;`

` `

3.    

`&#10;`

` `

4.    

`&#xa;`

` `

5.    

`&#x9;`

` `

6.    

`&#9;`

` `

7.    

` `

` `

8.    

` `

` `

9.    

`&gt;`

`>`

10.

`&lt;`

`<`

11.

`&amp;`

`&`

12.

`&apos;`

`'`

13.

`&quot;`

`"`

c.      Разделение текстового блока, содержащего блок символьной информации CDATA

Тестовый блок, содержащий блок CDATA, разделяется на следующие блоки:
  • Текст до блока CDATA;
  • Блок CDATA;
  • Текст после блока CDATA.

В текстовых блоках, отличных от CDATA, полученных в результате разделения, выполняется снятие экранирования по правилам, приведенным в таблице 11. Для блока символьных (CDATA) данных снятие экранирования и последующее кодирование не выполняются.

Примечание: После завершения кодировки текстовые блоки, разделенные на части, соединяются.

d.      Обработка блоков размером до 11 символов (включительно).

После снятия экранирования выполняется кодирование текста по правилам, приведенным в таблице 12.

Таблица 12 - Кодирование блоков размером  до 12 символов.

Кодируемый символ

Значение после кодирования

Условия кодирования

1.    

`<`

`&lt;`

всегда

2.    

`&`

`&amp;`

всегда

3.    

` `

`&#xd;`

всегда

4.    

`>`

`&gt;`

если первый символ в блоке (включая пробелы и переводы строк) или после символа `]`

e.      Обработка блоков размером от 12 символов (включительно).

Блоки размером от 12 символов, разделяются на части по 512 символов.

Примечание: Если блок больше или равен 12 символов и не превосходит 512 символов, то блок не разделяется.

В каждой из частей блок выполняется кодирование по правилам, приведенным в таблице  13.

Таблица 13 - Правила  кодирования блока размером от 12 символов (включительно).

Кодируемый символ

Значение после кодирования

Условия кодирования

1.    

`<`

`&lt;`

всегда

2.    

`&`

`&amp;`

всегда

3.    

` `

`&#xd;`

всегда

4.    

`>`

`&gt;`

если первый символ в блоке (с учетом пробелов и переводов строк) или после символов `<`, `&gt;`, `&`, `]`

Примечание: После завершения кодировки текстовые блоки, разделенные на части, соединяются.

f.      Декодирование атрибутов

Декодирование атрибутов XML выполняется в 2 этапа:

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

В атрибутах XML сообщения выполняется замена пробельных символов (перевод строки, пробел, символ перевода каретки, табуляция) на пробел.

Снятие экранирования выполняется по правилам, приведенным в таблице 11.

Кодирование атрибутов выполняется в соответствии с правилами, указанными в таблице 14

Таблица 14 - Правила снятия экранирования

Символ с экранированием

Символ после снятия экранирования

1.    

`&#xd;`

` `

2.    

`&#13;`

` `

3.    

`&#10;`

` `

4.    

`&#xa;`

` `

5.    

`&#x9;`

` `

6.    

`&#9;`

` `

7.    

` `

` ` (символ пробела)

8.    

` `

` ` (символ пробела)

9.    

` `

` ` (символ пробела)

10.

` `

` ` (символ пробела)

11.

`&gt;`

`>`

12.

`&lt;`

`<`

13.

`&amp;`

`&`

14.

`&apos;`

`'`

15.

`&quot;`

`"`

Кодирование атрибутов выполняется в соответствии с правилами, указанными в таблице 15

Таблица 15 - Правила снятия экранирования в атрибутах XML-сообщения.

Кодируемый символ

Значение после кодирования

Условия кодирования

1.    

`<`

`&lt;`

всегда

2.    

`&`

`&amp;`

всегда

3.    

`"`

`&quot;`

всегда

4.    

` `

`&#xd;`

всегда

5.    

` `

`&#xa;`

всегда

6.    

` `

`&#x9;`

всегда

Развёрнутый пример результата трансформации XML представлен в приложении Б. Образцовая реализация алгоритма на Java для Apache Santuario представлена в приложении Г.

Сценарии тестирования алгоритма приведены в приложении Д. Для использования сценариев их необходимо сохранить в файлах в кодировке UTF-8.


Авторизуйтесь, чтобы оставить комментарий к статье