ПРИЛОЖЕНИЕ  2

Интерпретация XSLT

Описание XML (Extensible Markup Language) можно посмотреть в http://www.w3.org/TR/1998/REC-xml-19980210 и http://www.w3.org/XML/.

Описание XSL Transformations (XSLT) можно найти в http://www.w3.org/TR/xslt .

Язык описания документов (DTD) здесь никак не используется. Без всякого сомнения, использовать DTD в данной задаче имеет смысл.

В настоящем параграфе описывается применение суперкомпилятора к интерпретатору языка трансформаций XSLT. Для понимания содержания никаких особых знаний в области XML не требуется. Примеры достаточно прозрачны.

Здесь предлагается один из возможных способов организации работы по применению суперкомплятора в достаточно сложных условиях, в результате чего получаем рабочий инструмент для реальной практической задачи.

Перечислим отличия этой задачи от других задач данного пособия.

Правила преобразований задаются документом XSLT. Эти правила преобразуют некоторый класс документов XML. Оба документа, и документ XSLT, и документ XML, имеют общий язык описаний, который, по многим соображениям, имеет смысл преобразовать в рефал-выражения. Парсер, преобразующий документы XML в рефал-выражения, реализован в программе xml_ref.ref , там же имеется обратный парсер.

Пусть e.XSLT - правила трансформации, записанные как XML-документ, e.XML - документ (произвольный), к которому эти правила будут применяться, XML_REF - парсер, REF_XML - обратный парсер. Int - интерпретатор правил трансформации у которого первым аргументом является e.XSLT, а вторым - произвольный XML-документ e.1.

Тогда задание на суперкомпиляцию выглядит так

        <Int (<XML_REF e.XSLT>) (e.1)>;

Пусть INT - функция, построенная суперкомпилятором. Тогда

        <REF_XML <INT <XML_REF e.XML >>> 

будет строить преобразованный документ e.XML.

Мы видим, что парсер используется дважды: на этапе суперкомпиляции и на этапе выполнения построенной суперкомпилятором программы. Мы ввели две различные входные точки в парсер.

Далее, в MST-схеме должен присутствовать документ e.XSLT, который всегда имеется в виде файла, и добавлять к нему по строчке в начале и в конце для получения MST-схемы не совсем практично. Суперкомпилятору достаточно получить лишь имя документа e.XSLT. Мы написали небольшую программу xiparm.ref , которая по имени документа строит задание на суперкомпиляцию из одной строчки. Пример подобного задания можно посмотреть в файле xi.mst.

В bat-файле xi.bat содержится задание на полный демонстрационный цикл задачи, включая исполнение построенной программы. Демонстрационные примеры занумерованы и имеют одинаковые префиксы. Ясно, что легко перейти к произвольным именам.

Программа xi.ref - интерпретатор XSLT, которая подвергается суперкомпиляции, при этом, помимо парсера, используется функция xiimpl.ref для выполнения дополнительного парсирования. Функция get_in.ref используется на этапе выполнения построенной программы.

Суть функции get_in.ref сводится к извлечению данных по имени на этапе исполнения результирующей программы. Идея введения этой функции оказалась успешной и плодотворной. Отметим, что без этой функции получались программы большого объема.

Чуть-чуть про функционирование программы. Постоянно работающая функция Int имеет формат

   <Int s.Tag (e.XSLT) (e.XML) (e.All)>

где e.All - правила трансформации в первоначальном виде, они не меняются, используются, где надо (в частности, при рекурсивных обращениях), размножаются несколько раз, а суперкомпилятор убирает их из выходной программы. Тем самым, стиль программирования не является обычным, он использует свойства суперкомпилятора. (тем самым сравнительный анализ количества рефал-шагов является завышенным, так как первоначальный алгоритм явно неэффективен).

e.XSLT - фрагменты e.All, которые требуются в данный момент интерпретации,

s.Tag - текущий тэг, от него тоже зависит функционирование интерпретатора, в дальнейшем может понадобиться список тэгов, отражающий глубину вложенности дерева.

e.XML - входной документ XML, он присутствует как бы мысленно, я его не меняю, только считываю. И это правильно. Когда я пытался извлекать оттуда данные на этапе суперкомпиляции, то получались необозримые программы. Когда я ввел функцию get_in - ситуация резко улучшилась. Оказалось, что суперкомпилятору удобнее работать не с данными из XML непосредственно, а с функцией, извлекающей эти данные. Как не странно, догадался я до этого, проводя аналогию с параграфом из пособия "Получение формул в математике". Разные уровни обработки информации - можно работать с числами в арифметике, а можно работать с арифметическими операциями.

Далее приводим 7 примеров с номерами N = 1, 2, 3, 4, 5, 6, 9. В каждом из них приводится четыре ссылки. Файлы с именами без "_" являются исходными данными. Если в имя входит "_" , то файл порождается в процессе.

Файл xiN.xsl выполняет роль e.XSLT, файл xiN.xml - роль e.XML. Результирующая после работы суперкомпилятора программа имеет имя r_xiN.ref. Эта программа читает файл xiN.xml в качестве исходных данных и помещает преобразованный документ в файл s_xiN.htm.

Пример 1.xi1.xsl , xi1.xml , r_xi1.ref , s_xi1.htm

Mark Johnson, XML for Absolute Beginner, www.javaworld.com/javaworld/jw-04-1999/jw-04-xml_p.html

На основе этого примера построена статья Valentin F. Turchin "Refal: the Language for XML Processing".

Пример немного модифицирован, в частности, убран условный оператор. Думаю, что принципиальных сложностей он (оператор) не принесет. Аналогично, в примере 2 убрана сортировка. Результат s_ex1.htm в этом и других примерах можно посмотреть в двух видах, а именно, в виде файла HTML и в виде интерпретации его имеющимся браузером.

Пример 2 .xi2.xsl , xi2.xml , r_xi2.ref , s_xi2.htm

Uch Ogbuji. Practical XML with Linux, Part 1. Getting things done with the Extensible Markup Language, www-4.ibm.com/software/developer.../xml-for-linux1.htm

Здесь совсем легко ввелись новые правила трансформаций xml:element, sml:attribute.

Пример 3. .xi3.xsl , xi3.xml , r_xi3.ref , s_xi3.htm

XSL Transformation (XSLT) Version 1.0, www.w3.org/TR/xslt , Appendices, D.Examples.

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

Пример 4. .xi4.xsl , xi4.xml , r_xi4.ref , s_xi4.htm

Взят из тех же материалов.

Пример 5. .xi5.xsl , xi5.xml , r_xi5.ref , s_xi5.htm

Это мой собственный пример - попытылся придумать нечто, отличающееся от остальных примеров - там все время генерируется html-тексты. По описанию конечного автомата в виде документа XML генерируется рефал-программа, которая благополучно исполняется. В качестве примера xi5.xml был выбран пример признака делимости на 3.

Пример 6. .xi6.xsl , xi6.xml , r_xi6.ref , s_xi6.htm

Пример взят из популярной сайт-школы по XML http://www.refsnesdata.no/xml в качестве совсем простенького примера трансформаций.

Пример 7. .xi9.xsl , xi9.xml , r_xi9.ref , s_xi9.htm

Пример построен с целью получения каких-то временных оценок исполнения программ. В результате применения данных правил трансформации происходит размножение исходного дерева. Файл xi9.xml имеет объем 231 байт, результирующий файл s_xi9.htm - 1224 байт. В результате повторного применения правил трансформации получается файл объемом примерно 11К, после третьего этапа - файл объемом 130К (мы их не приводим по понятным причинам).

Мы продублировали файл в 11К трижды. Таким образом, нижеприведенные цифры относятся к правилам трансформаций xi9.xsl, примененным к файлу объемом в 33К, в результате строится файл объмом 388К. Время выполнения интерпретатора без суперкомпиляции составило 8 секунд, после суперкомпилятора время выполнения составило 2 секунды (Pentium 200). Итак, можно говорить о четырехкратном увеличении быстродействия.

Список всех ссылок этого параграфа пособия по суперкомпилятору.

xi.bat , xiparm.ref , xi.mst - организация полного цикла работы этого примера.

xi.ref , xiimpl.ref - суперкомпилируемый интерпретатор XSLT.

get_in.ref - функция, используемая на этапе выполнения построенной программы.

xml_ref.ref - парсер из XML в рефал и обратно.

.xi1.xsl , xi1.xml , r_xi1.ref , s_xi1.htm - пример 1.

.xi2.xsl , xi2.xml , r_xi2.ref , s_xi2.htm - пример 2.

.xi3.xsl , xi3.xml , r_xi3.ref , s_xi3.htm - пример 3.

.xi4.xsl , xi4.xml , r_xi4.ref , s_xi4.htm - пример 4.

.xi5.xsl , xi5.xml , r_xi5.ref , s_xi5.htm - пример 5.

.xi6.xsl , xi6.xml , r_xi6.ref , s_xi6.htm - пример 6.

.xi9.xsl , xi9.xml , r_xi9.ref , s_xi9.htm - пример 7.