Emacs для начинающих

       

Дилемма 5.Узлы или ребра?


DOM представляет собой модель, которая в качестве сущностей использует узлы. Этот метод хорош для хранения документа в виде объектов в памяти, но может стать значительной проблемой при хранении иерархических данных в таблицах SQL. Для хранения, напротив, более подходящим будет метод представления, в котором сущностью являются связи между узлами. Дополнительным условием является наличие у всех узлов однозначных идентификаторов, так чтобы было возможно идентифицировать два одинаковых сестринских узла. Поскольку все связи возможно представить в виде простой таблицы, то реберное представление позволяет просто (с учетом наличия идентификаторов) хранить XML в SQL базе данных с максимальной степенью детализации.

Рассмотрим простой пример, иллюстрирующий сказанное. Допустим, у нас есть простая XML-схема (модель статьи):

Рисунок: Модель статьи

На основе этой модели можно создать такой валидный документ:

<?xml version="1.0" encoding="UTF-8"?> <article codename="XML"> <head> <filename>Text</filename> <author>Vasia Pupkin</author> <email>ya_vasia@bigmir.net</email> <editor>ChebotarjovA.</editor> <chars>456</chars> </head> <body> <title>XML parsing</title> <annotation>It's just an example.</annotation> <data> <par> Body text of article. </par> </data> </body> </article>

Добавим к каждому элементу идентификатор для введения определенности в случаях, когда есть последовательность однотипных элементов (вообразите, что у вас есть отношение «первый параграф раздела», но сам-то раздел должен быть идентифицирован). Поскольку у текста и комментариев не может быть дочерних узлов, то для них можно не вводить идентификаторов. Можно ввести культуру (правило) присвоения имен узлам, можно их просто вынимать из «черного ящика» — главное, что они должны быть уникальными. Для автоматизации такой операции нам, очевидно, пригодится SAX. Условно такой документ может выглядеть так (на самом деле его нет необходимости явно генерировать):

<?xml version="1.0" encoding="UTF-8"?> <article ID="1" codename="XML"> <head ID="2"> <filename ID="3">file.rtf</filename> <author ID="4">Vasia Pupkin</author> <email ID="5">ya_vasia@bigmir.net</email> <editor ID="6">Chebotarjov A.</editor> <chars ID="7">456</chars> </head> <body ID="8"> <title ID="9">XML parsing</title> <annotation ID="10">It's just an example.</annotation> <data ID="11"> <par ID="12"> Body text of article. </par> </data> </body> </article>
<
В результате мы можем составить такую таблицу ребер (убедитесь, что по этой таблице можно восстановить исходный документ).



ORDER Источник Тип ребра Приемник Значение
0   подэлемент article.1 статья про XML
1 article.1 атрибут codename XML
2 article.1 подэлемент head.2  
3 head.2 подэлемент filename.3  
4 filename.3 текст   file.rtf
5 head.2 подэлемент author.4  
6 author.4 текст   Vasia Pupkin
Может быть несколько способов реберного представления — в зависимости от терминологии и предполагаемого использования. Значение текста, например, можно считать и значением, и «приемником» (поскольку это все-таки узел). У нас не показаны также «сестринские» связи — а это может оказаться полезным, если важно искать соседние подэлементы. Иногда будет выгодно указывать только первый дочерний элемент и потом — связи типа «следующий».

Можно также нумеровать атрибуты и исключить еще один столбец, но поскольку событие «прибыл атрибут» не предусмотрено в SAX, то сам процесс такой нумерации потребует дополнительного кодирования в духе foreach.

Кроме того, не показана алгебра документов — то есть способ учета документов как атомарных величин. Возможно, для этого будет создана отдельная таблица традиционного формата с полями DOC_ID, DOC_NAME, DOC_DESСRIPTION, DOC_LASTMOD и в том же духе.

Как видно, это представление легко укладывается в одну SQL-таблицу и может быть сравнительно прямолинейно восстановлено с использованием SAX. Фактически многие «объектные» базы данных работают именно таким образом, сохраняя документы в виде реберного представления и восстанавливая их в момент загрузки.

Реберное представление позволяет также оптимизировать поиск — особенно если таблица индексирована по искомому полю. Например, очень легко найти элемент (ы) с заданным индексом, именем, значением атрибута, связью и так далее.


Содержание раздела