Click HERE to return to our International home page
Концепты Заметки МЕТА Флэнг Онлайн Модули Библио Форум



ГлавнаяФлэнг > Описание > XML. Часть 2 
 






• Факториал
• Арифметика
• Пример логической программы
• Структуры и термы
• Атомы
• Списки во Флэнге
• XML- документы
• Векторы
• Таблицы
• Перечисления
• XML-документы (продолжение)



Описание встроенных функций

 



XML-документы: часть 2 (morexml.fln)

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

xElem/4
4-х аргументная структура, определяющая XML-элемент
xDoc/1
структура, определяющая внешнюю вершину XML-документа
xEntityRef/1
структура, определяющая сущности XML
xCDATA/1
структура, определяющая необрабатываемые данные. Это структура позволяет явно использовать в тексте ключевые символы XML, например, '<'
xComments/1
структура, определяющая вершину комментариев
xPI/3
структура для определения XML-инструкций
xNS/2
структура, задающая пространства имен
Рассмотрим использование этих структур более подробно.

xElem/4

Основной из предопределенных структур, с помощью которых строятся XML-документы, является структура xElem/4:

  ?- xElem("hello-elem", newHash(["id"/"hello"]), 
["Hello, everybody!"], _);

<hello-elem id="hello">Hello, everybody!</hello-elem>
В этом примере XML-документ вводится во Флэнг-систему в термальном виде. Флэнг-система возвращает саму эту же структуру, используя по умолчанию стандартный XML-формат. Структура xElem имеет 4 аргумента:
  xElem(TagName, TableOfAttrs, Contents, Namespaces)
Чтобы данная структура корректно представляла XML-документ, каждый из ее аргументов должен сыграть определенную роль:
TagName
первый аргумент содержит имя элемента, представленное в виде строки или атома
TableOfAttrs
этот аргумент определяет атрибуты XML-элемента. Атрибуты представляются в виде хэш-таблицы. Например, чтобы породить множество атрибутов для элемента
  <ha a="1" b="ququ"/>
нужно определить хэш-таблицу:
  newHash(["a"/1, "b"/"ququ"])
Вместо хэш-таблицы в качестве второго аргумента допустима и свободная переменная, которая воспринимается Флэнгом как пустое множество атрибутов.
Contents
содержимое элемента. Должно быть списком, либо вектором XML-термов. Допускаются вложенные списки и векторы, а также их смешение. Флэнг при "разворачивании" содержимого элемента автоматически использует перечисление типа eFlat/1. Пример:
  ?- vec:=newVector(["2 ", ["3 "]]);

true

?- ^vec;

("2 ", ["3 "])

?- xElem("digits", FreeVar, ["1 ", [^vec], [["4 "]]], _);

<digits>1 2 3 4 </digits>
Пустой список в качестве третьего аргумента соответствует пустому XML-элементу
  ?- xElem("empty-elem", _, [], _);

<empty-elem/>
Namespaces
Этот аргумент содержит информацию о пространствах имен. Свободная переменная в качестве пространства имен означает пространство имен по умолчанию. Пространству имен - очень важному механизму организации XML-документов - будет посвящена одна из следующих главок.
Приведем простые примеры использования структуры xElem. Вложенность элементов в XML-документе описывается через вложенность термов:
  ?- xElem("a", _, [xElem("b", _, [], _)], _);

<a><b/></a>
Манипулировать XML-документами можно опосредованно с помощью функций:
  ?- makeElem(Attr, Conts) :-
xElem("elem", newHash(["id"/Attr]), [Conts], _);

?- makeElem("elem1",
makeElem("subelem", makeElem("subsubelem", [])));

<elem id="elem1"><elem id="subelem"><elem id="subsubelem"/>
</elem></elem>

Основным методом работы с XML-документами является рекурсия по глубине вложенности элементов. Рассмотрим пример: функция countElem(XMLDoc) подсчитывает число элементов в документе XMLDoc:
countElem(xElem(_, _, Conts, _)) :-
1 + countConts(eFlat(Conts))
;
countElem(_) :- 0;

countConts(Enum) :- exhausted(Enum), 0
;
countConts(Enum) :-
N = countElem(eValue(Enum)),
N + countConts(eNext(Enum))
;
В определении этой функции используются стандартные рекурсивные приемы, которые позволяют обходить XML-дерево - элемент за элементом - и проводить нужные преобразования. Рекурсия получается "двухуровневая". Функция countElem работает на уровне XML-элементов, а функция countConts обеспечивает цикл по элементам содержимого XML-элементов. Обратите внимание на использование перечисления eFlat, которое позволяет абстрагироваться от конкретного формата представления содержимого элементов.
  ?- xdoc() :- <a b="1"><c><a b="5"/>a</c></a>;

?- countElem(xdoc());

3

Функция countAttr(XML, AttrName), определенная ниже, подсчитывает в документе XML число элементов, содержащих атрибут с именам AttrName.

countAttr(xElem(_, A, Conts, _), AttrName) :-
hasKey(A, AttrName),
1 + countContents(eFlat(Conts), AttrName)
;
countAttr(xElem(_, A, Conts, _), AttrName) :-
countContents(eFlat(Conts), AttrName)
;
countAttr(_, _) :- 0
;
countContents(Enum, _) :- exhausted(Enum), 0
;
countContents(Enum, AttrName) :-
N = countAttr(eValue(Enum), AttrName),
N + countContents(eNext(Enum), AttrName)
;
Данная программа организована аналогично предыдущей - на основе двухуровневой рекурсии по элементам и содержимому элементов. Пример использования функции
  ?- countAttr(xdoc(), "b");

2
Приведем еще один пример программы, которая преобразует XML-документ, заменяя имена тегов. Функция replaceElem(XDoc, OldName, NewName) переименовывет элементы XDoc с именем OldName на NewName
replaceElem(xElem(Old, A, Conts, NS), Old, New) :-
xElem(New, A,
replaceConts(eFlat(Conts), Old, New), NS)
;
replaceElem(xElem(Other, A, Conts, NS), Old, New) :-
xElem(Other, A,
replaceConts(eFlat(Conts), Old, New), NS)
;
replaceElem(Other, _, _) :- Other;

replaceConts(Enum, Old, New) :- exhausted(Enum), []
;
replaceConts(Enum, Old, New) :-
Result = replaceElem(eValue(Enum), Old, New),
[Result | replaceConts(eNext(Enum), Old, New)]
;
Пример вычисления:
  ?- replaceElem(xdoc(), "a", "hrrr");

<hrrr b="1"><c><hrrr b="5"/>a</c></hrrr>
Легко заметить, что все три приведенные выше программы очень похожи друг на друга с точки зрения организации обхода по структуре XML-документа. Последняя программа демонстрирует, каким образом XML-документ может во Флэнге преобразовываться.

xDoc/1

Следующей по важности структурой является xDoc/1. Эта структура является внешней структурой XML-документа и (информация для тех, кто работал с XML на Java) аналогична элементам класса Document в библиотеке jdom. Класс Document и структура xDoc необходимы, поскольку на самом внешнем уровне у xml-документа может быть несколько узлов. Только один из этих узлов являятся XML-элементом, остальные же могут быть xml-инструкциями, ссылками на dtd-файлы как, например, в XML-документе

  <?xml version="1.0" encoding="ISO-8859-1"?>
<?translate russian encoding="win-1251"?>
<a/>
Этот документ на внешнем уровне содержит три элемента - две инструкции и тег с именем a. Они и будут содержимым структуры xDoc/1, которая имеет следующий формат:
    xDoc(Contents)
Формат аргумента Contents аналогичен формату третьего аргумента структуры xElem (списки или вектора).

Подчеркнем, что xDoc/1 - всегда внешняя структура. В правильно построенном XML-терме аргумент Contents содержать элементы xDoc/1 не может, поскольку это не соответствует стандартной структуре XML-документа.

Правила использования xDoc/1 во Флэнге следующие:

  1. При чтении XML-файлов с помощью функции readXML документы всегда обрамляются структурой xDoc. Это надо учитывать при доступе к элементам XML-документа, загруженного с помощью этой функции.
  2. XML-термы, представленные во Флэнг-программе в стандартном XML-синтаксисе, транслируются Флэнг-системой в представление, не содержащее структуру xDoc/1. Например, тело правила
      segm() :- <a b="1"><c/></a>;
    при трансляции во внутреннее представление Флэнг-системы переводится в терм
      xElem("a", newHash(["b"/1]), 
    [xElem("b", newHash([]), [], _)], _)
    Таким образом, при формировании этого XML-терма используется только структура xElem/4.
  3. При записи XML-терма в XML-файл, например, с помощью функции writeXML, обрамлять этот терм структурой xDoc/1 не обязательно. Если xDoc явно отсутствует, то Флэнг-система добавит его автоматически.
Если вернуться к определению функции countElem/1, то следует обратить внимание на то, что данное определение не будет работать на XML-термах, загруженных из XML-файлов, поскольку в программе не учтен случай, когда внешним термом является xDoc. Имеются несколько возможностей для учета этой ситуации. Во-первых мы можем явно добавить в определение функции countElem/1 правило для xDoc:
  countElem(xDoc(Conts)) :- countConts(eFlat(Conts));
Однако этот способ, вероятно, не самый удачный, поскольку мы знаем, что в XML-документе структура xDoc/1 может встречаться только один раз, и то на внешнем уровне. Поэтому только что определенное правило будет проверять заведомо неподходящие вершины, что неэффективно. Более подходящим является вариант определения отдельной внешней функции, запускающей процесс вычисления, например:
  count(xDoc(Conts)) :- countConts(eFlat(Conts));
count(XML) :- countElem(XML);

xEntityRef/1

Эта одноместная структура задает еще одну важнейшую конструкцию XML - сущности (entities). В частности, часто употребляемая сущность XML
  &lt;
обозначающая значок "меньше", используемый в XML для определения тегов, во Флэнге определяется с помощью структуры
  xEntityRef("lt")
При трансляции XML-термов Флэнга в файл, например с помощью функции writeXML/3, эта структура транслируется в стандартное представление сущностей, начинающееся с амперсанда '&', и заканчивающееся точкой с запятой.

xCDATA/1

Обычный текст в XML-документе понимается как размеченный текст. Это значит, что парсер (транслятор) ищет в нем вкрапления тегов и других специальных элементов языка XML. В частности, значок '<' парсером однозначно понимается как начало тега XML-элемента. Чтобы использовать этот и другие подобные значки как обычные символы, необходимо прилагать специальные усилия, например, определять эти символы через сущности. Имеется и иной способ - запретить парсеру обрабатывать некоторый сегмент текста. Для этого служит блок CDATA. В синтаксисе XML такой блок организуется следующим образом:
  <![CDATA[  ...необрабатываемый текст...  ]]>
Во Флэнге для выделения необрабатываемого текста служит специальная структура - xCDATA:
  xCDATA("...необрабатываемый текст...")
Работа этой структуры демонстрируется в следующем примере:
  ?- xElem(a, _, ["&"], _);

<a>&amp;</a>

?- xElem(a, _, [xCDATA("&")], _);

<a><![CDATA[&]]></a>s
В первом запросе значок амперсанда транслируется Флэнгом в соответствующую сущность, поскольку содержимое элемента (третий аргумент xElem) понимается как размеченный текст, поэтому вхождения в текст символов, являющихся специальными символами XML, должны быть обработаны. Во втором случае значок амперсанда остается неизменным.

xComments/1

Данная структура служит для включения в XML-термы комментариев. В стандартном синтаксисе комментарии включаются в XML-документ в следующем формате:
  <!--   ...комментарии...   -->
Пример организации комментариев с помощью структуры xComments/1 во Флэнге:
  ?- xElem(a, _, [xComments("комментарии")], _);

<a><!--комментарии--></a>

Processing instruction

Элемент "инструкция по обработке" (processing instruction) позволяет включать в XML информацию, предназначенную для методов, которые ориентированы на обработку данного документа. Любой xml-документ начинается с такой инструкции, информирующей о версии XML и задающей дополнительную информацию для обработчиков. Например, в следующей преамбуле XML-документа включена информация о системе кодировки символов:
  <?xml version="1.0" encoding="ISO-8859-1"?>
Синтаксически инструкция начинается и заканчивается знаком вопроса, обрамленным стандартными угловыми скобками. В приведенном примере имеем имя инструкции (идентификатор xml), а также параметры инструкции, которые заданы в формате 'атрибут'='значение'. Такой формат параметров является наиболее удобным, хотя с точки зрения стандарта XML совсем не обязательным. Например, возможен такой вариант:
   <?translate russian encoding="ISO-8859-1"?>
Здесь параметр russian состоит из одного слова. Инструкции по обработке реализуются во Флэнге с помощью специальной структуры xPI/3. Инструкция из последнего примера будет представлена с помощью данной структуры в следующем виде:
  xPI("translate", newHash(["encoding"/"win-1251"]), 
"russian encoding='win-1251'")
Первый аргумент - имя (идентификатор) инструкции. В данном случае это translate. Во втором аргументе с помошью таблицы собраны параметры, имеющие формат 'атрибут'='значение'. В третьем аргументе все параметры собраны в виде одной строки. Поскольку параметры в формате 'атрибут'='значение' включены и в третий аргумент, информация во втором аргументе структуры является избыточной. Однако это весьма полезно на практике, поскольку обеспечивает легкий доступ к "хорошо представленным" параметрам. Для других параметров при обработке инструкции придется обрабатывать строку - третий аргумент.

xNS/2

С помощью двуместной структуры xNS/2 определяется пространство имен документа. Стандартное использование этой структуры - в качестве четвертого аргумента структуры xElem/4. Формат у xNS следующий:

  xNS('пространство имен данного элемента', 
'таблица доп. пространств имен')
Первый аргумент определяет пространство имен текущего элемента. Во втором аргументе в виде таблицы перечисляются пространства имен, в которых могут определяться подъэлементы данного элемента.

Заметим, что если используется только пространство имен по умолчанию, то применять структуру xNS/2 не обязательно. Вместо этого в качестве четвертого аргумента xElem/4 можно подставить свободную переменную. Мы этим довольно часто пользовались выше.

Во Флэнге реализованы полноценные, и в то же время прозрачные и простые механизмы работы с пространствами имен. Подробно эти механизмы описаны в главке "Пространства имен и их поддержка во Флэнге".


Программа на Флэнге (morexml.fln):

???


mПримечания

???


Работа в интерпретаторе:

???


m Что делалось

???







Контакты
664003 Иркутск, ул. К. Маркса, 1, Иркутский государственный университет, Центр новых информационных технологий

email

 

Заметки*
Открытая система
Пакетирование
XML
Тексты
Естественнонаучные ресурсы
Ресурсы как модели
Форматы ресурсов
Информационные уровни
Трудности
Учебные объекты
"Опыт человечества"
Коммуникативные системы
О пользе RSS
Проблема интернета
Осмысленный интернет
Идентификация ресуров
Метаданные и будущее
Дублинское ядро
Метаданные и знания
Онтологии
*Набор кратких заметок и высказываний, посвященных различным аспектам информатизации образования. Что называется - "заметок по поводу...".

Онлайн-сервисы**
• Сайт кафедры математического анализа
Форум с поддержкой математических формул.
• Flang-online
• TeX->MathML->GIF.
• MathML->GIF.
• Flang-Meta.
QTI-тестирование с поддержкой математических формул.
• Meta-ZIP
• UDC
• Font-Test
**список эксперементальных сервисов, на которых апробировались реализуемые группой технологии. Сервисы созданы на основе базовых модулей.

Библиотека***
Онтологии и метаописания
Учебные объекты
Языки программирования и логика
eLearning and Knowledge
Digital Libraries and Repositories
Книжки и учебники
***Коллекция публикаций по тематике, собранная из открытых интернет-источников.




.



Copyright ® 2002-2005, TeaCODE.com