В этой лекции излагаются основы
Немногие приложения могут делать что-либо полезное, не получая
информации извне, и приложения Mozilla не составляют исключения.
Эта лекция посвящена, прежде всего, концепциям, лежащим в основе
Для того чтобы понять смысл многих компьютерных технологий, часто
достаточно беглого взгляда. Однако эта стратегия не работает при
встрече с действительно новыми и необычными подходами. В этом случае
приходится притормозить и заняться систематическим изучением
материала.
Итак, что же такое
Я ходил в магазин. Луна состоит из зеленого сыра. Том, Дик и Гарри – братья. Эта функция никогда не используется. Каждый человек должен найти собственный путь в жизни.
Неважно, являются ли эти утверждения истинными. Неважно, каков их
источник, и согласен ли с ними хоть кто-нибудь. Важно то, что их можно
записать некоторым универсальным способом (в данном случае – на
русском языке). Записывая факты, мы перемещаем их из своего сознания
туда, где их можно зафиксировать в соответствии с определенными
правилами или
Окружающий мир, включая сферу информационных технологий,
насыщен "фактоподобной" информацией. Однако подавляющее
большинство сведений не представлено в форме, удобной для обработки
фактов. Лишь немногие программисты в своей практике сталкиваются со
специализированными системами обработки фактов, однако код любого из
них содержит множество подразумеваемых фактов. Эти подразумеваемые
факты используются для решения других задач. Напротив,
Примером крайне примитивной и тривиальной системы хранения
"фактоподобной" информации, не использующей формата
<A HREF="http://www.mozilla.org/" ADD_DATE="961099870" LAST_VISIT="1055733093" ICON="http://www.mozilla.org/images/mozilla-16.png" LAST_CHARSET="ISO-8859-1"> The Mozilla Organization </A>
Этот фрагмент содержит ряд сведений об указанном URL: дату его
добавления к списку закладок, дату последнего посещения и т.д.
Атрибуты XML, в которых хранится эта информация, могут рассматриваться
как простые данные или как описание фактов. Хотя для описания фактов
можно использовать простой XML (или архаичный псевдо-HTML, как в этом
примере), лучше использовать специализированное приложение XML с
определенным синтаксисом. Как раз таким приложением является
Многие специалисты называют информацию такого рода метаданными.
Предполагается, что этот термин позволяет разграничить информацию (в
данном случае – содержимое web-документа, на который указывает URL) и
"информацию об информации" (описание документа и самого
URL), которая и называется метаданными. На практике, если программист
пишет код для работы с файлом закладок, единственной интересной для
него информацией являются так называемые метаданные – содержание этого
файла. С его точки зрения метаданные оказываются обычными данными, с
которыми он должен работать. То, что для одного человека является
метаданными, для другого – просто данные. Таким образом, при изучении
Говоря коротко, термин "метаданные" часто используется
без необходимости. С точки зрения программиста единственным элементом
<Description about="file:///local/writing/" open="true"/>
Говоря попросту, эта строка утверждает, что папка /local/writing/
открыта. Более строгая интерпретация в терминах open, значением (объектом) которого является
анонимная строка литералов "true"". Это довольно
неуклюжий язык, и сейчас нам предстоит разобраться, что все это
означает.
Наконец, следует сказать, что
На схеме в начале этой лекции показано, что поддержка
К сожалению, производительность работы с
Классический пакет приложений Mozilla в значительной степени
основан на
Классический браузер и Netscape 7 создают и используют
Изучение
Синтаксис XML отличается высокой избыточностью. Когда наши глаза и
мозг поглощены разбором формального синтаксиса, без надлежащего опыта
бывает трудно сосредоточиться на содержательных вопросах. Даже
разработчики официальной спецификации
Популярные введения в
Кроме того,
Наконец,
Тем не менее,
В основе синтаксиса любых приложений XML лежит концепция элемента,
который часто соответствует одному тегу. В основе
Программист может получить первое представление о мире фактов по
аналогии с известными технологиями, которые до некоторой степени
"фактоподобны". В качестве примеров можно привести язык SQL
и утилиту make. Управление записями в базе данных при помощи таких
INSERT, DELETE и особенно SELECT до некоторой
степени сходно с управлением фактами. Запрос к базе данных аналогичен
запросу к системе обработки фактов. С другой стороны, правило
командного файла утилиты make(1), на основе которого утилита
определяет, какие файлы нуждаются в новой компиляции, также
"фактоподобно". Правило из командного файла можно
рассматривать как факт о файлах и "целях" ( target ) утилиты make. Еще один пример "фактоподобного" командного файла –
конфигурационный файл программы sendmail, весьма сложный для
чтения.
У всех этих систем есть общее свойство: хранимые элементы данных
независимы друг от друга и содержат несколько значений – каждый факт
состоит из нескольких частей (полей в случае записи в базе данных,
цели и зависимостей - в случае файла make ). Работа с фактами
подразумевает использование специального приложения, будь то сервер
баз данных, утилита make или агент пересылки почты. Это приложение
обрабатывает факты, после чего передает результаты пользователю или
другой программе
Факты используются для описания и моделирования данных.
Программисты, как правило, используют для моделирования структуры
данных. Те программисты, которым приходится заниматься
проектированием, могут использовать для этого словари данных и
диаграммы
Пожалуй, простейший способ понять, чем факты отличаются от
традиционных данных, – записать то и другое. Предположим, что мальчик
и его собака играют с мячом на пляже. Описание этой ситуации,
включающее четыре объекта реального мира (мальчик, пляж, собака, мяч),
может храниться как структура данных или как факт. Начнем с обычных
структур данных. В JavaScript эти данные можно сохранить в форме
{boy:"Том", dog:"Спот", ball:"теннис", beach:"Уайкики"}
Эта запись довольно близка и к структурам данных в C/C++ ( struct ).
Ту же информацию можно сохранить и в виде массива JavaScript:
[ "Том", "Спот", "теннис", "Уайкики" ]
Все наши данные имеют один и тот же тип – строка, что соответствует идее массива. Массив с этими данными можно было бы создать и в C/C++. В программе на Perl можно было бы использовать список:
( "Том", "Спот", "теннис", "Уайкики", )
Существует много способов сохранить одни и те же данные, и каждый из них имеет свои достоинства и недостатки. Использование объекта или класса подразумевает, что все элементы данных (поля объекта) имеют общего владельца (объект), и во многих языках каждый из них имеет определенный тип. Использование массива подразумевает, что элементы пронумерованы и имеют один и тот же тип. Использование списка означает, что элементы упорядочены. Программист может выбрать наиболее подходящий вариант для конкретной задачи.
Информация может быть записана и в виде факта – с использованием кортежа.
< Том, Спот, теннис, Уайкики >
Однако в этом варианте и других, подобных ему,
<- Том, Спот, теннис, Уайкики ->
Каждый из элементов
Использование угловых скобок < и > намекает на существенную
разницу между
Обработка декларации-
Пример
В принципе,
Предположим, что нам необходимо зафиксировать эту ситуацию более
подробно. Типичный подход к моделированию – начать с выявления
существительных. На их основе могут быть спроектированы объекты,
var boy = { Pid:1, name:"Том", Did:null, Bid:null };
// name - имя
var dog = { Did:2, name:"Спот", Pid:null, Bid:null };
var ball = { Bid:5, type:"теннис", color:"зеленый" };
// type - тип, color - цвет
boy.Did = dog; // связать объекты друг с другом
boy.Bid = ball;
dog.Pid = boy;
dog.Bid = ball;
Аналогичное моделирование может быть выполнено при помощи
<- 1, Том, 2, 5 -> <- 2, Спот, 1, 5 -> <- 5, теннис, зеленый ->
Как и в случае реляционных данных, связи между объектами
представлены парами одинаковых значений в разных
Обе попытки моделирования позволили описать некоторые существенные
факты, но одновременно выявили ограниченность обоих подходов. Исходное
описание ситуации таково: "Том и его собака
| Модель с объектами | Модель с |
|---|---|
| Объект для Тома | |
| Объект для |
|
| Объект для зеленого теннисного мяча | |
| Том связан со |
Том, 1, 2 и 5 связаны между собой |
| Том связан с зеленым теннисным мячом | Зеленый теннисный мяч и 5 связаны между собой |
| (Можно вывести дополнительную информацию) | (Можно вывести дополнительную информацию) |
Таблица 11.1 несколько приукрашивает ситуацию, поскольку учитывает
подразумеваемое знание о назначении каждого объекта и
Традиционное решение этой проблемы – создать дополнительные
таблицы, объекты и т.п. Решение, подходящее для мира фактов, – сделать
каждое существующее отношение
Предикатами называется особая группа
<- 1, Том, хозяин, 2, играет-с, 5 -> <- 2, Спот, принадлежит, 1, играет-с, 5 -> <- 5, теннис, зеленый ->
В этом примере отношения имеют тот же статус, что и другие данные.
Первый
Теперь добавим к нашему жаргону еще одно слово.
Описание ситуации в листинге 11.3 все же не идеально, поскольку
некоторые
<- 1, Том, хозяин, 2 -> <- 1, Том, играет-с, 5 -> <- 2, Спот, принадлежит, 1 -> <- 2, Спот, играет-с, 5 -> <- 5, теннис, зеленый ->
Ценой некоторого дублирования информации мы смогли разделить
предикаты, и теперь наши
<- 1, имя, Том -> <- 1, хозяин, 2 -> <- 1, играет-с, 5 -> <- 2, имя, Спот -> <- 2, принадлежит 1 -> <- 2, играет-с, 5 -> <- 5, тип, теннис -> <- 5, цвет, зеленый ->
Теперь мы имеем дело только с триплетами. Триплеты с одним
предикатом лежат в основе практически всех систем работы с фактами.
Думая об обработке фактов, следует опираться на концепцию триплетов с
одним предикатом, а не произвольных
Стоит отметить, что на пути выделения предикатов и отношений можно зайти слишком далеко. Последние два триплета в листинге 11.5 отличаются от остальных. Теннис и зеленый представляют собой простые описательные свойства, а не элементы ситуации, такие как мальчик или мяч. Подобно тому, как можно создать чрезмерно нормализованную базу данных со многими таблицами или множество тривиальных классов в случае объектного проектирования, можно сформулировать и избыточное количество тривиальных фактов. Однако все зависит от задачи – если тривиальные факты представляют интерес в ее контексте, можно смело фиксировать их.
Поскольку триплеты широко используются, их элементы имеют
специальные названия. Как уже было сказано,
Факты об отношениях могут быть записаны различными способами.
Например, в языке
предикат(субъект, объект) plays-with(1,5) играет-с(1,5)
В языках
(предикат субъект объект) (plays-with 1 5) (играет-с 1 5)
Можно записывать такие факты и на естественном языке
субъект предикат объект 1 играет с 5
И, разумеется, факты об отношениях можно выразить на языке XML, для
чего и был разработан формат
<Description about="субъект" предикат="объект"/> <Description about="1" играет-с="5"/>
Наконец, для удобной и компактной записи фактов может
использоваться нотация для
<- субъект, предикат, объект -> субъект предикат объект
Если вы склонны придерживаться синтаксиса реального языка
программирования, можете следовать простой и ясной нотации
Рис. 11.1 Граф связей между кортежами 1 играет-с 5 5 тип теннис 1 имя Том 1 хозяин 2 2 принадлежит 1 2 имя Спот 5 цвет зеленый 2 играет-с 5
К настоящему моменту мы выработали подходящую структуру для описания факта. Какими же способами можно хранить ее в компьютере? Существует несколько вариантов.
Первый способ – хранить факты как набор независимых элементов. В
реляционной СУБД этому соответствуют отдельные записи в таблице с
тремя полями; в объектной технологии – коллекция элементов (например, set или ). Запись в
листинге 11.5 соответствует такому подходу.
Этот простой подход очень гибок. В любой момент можно добавить новые факты или удалить существующие. Не нужно поддерживать никакой внутренней структуры. Такое решение можно сравнить с обычным ведром – при необходимости вы просто "наливаете" в него факты или "выливаете" их.
Одно из главных преимуществ "ведра с фактами" – легкость объединения фактов из разных источников. Вы просто "наливаете" их в ведро, получая в результате одну большую коллекцию фактов. Когда вы обращаетесь к ней, все факты имеют одинаковый статус независимо от происхождения. Это просто объединение двух множеств.
Второй подход к хранению фактов основан на признании того, что
между отдельными фактами существуют связи, образующие некую структуру.
Она может храниться как традиционная структура данных, в которой связи
между
(рис 11.1) Связи между фактами, приведенными в листинге 11.5.Пожалуй, это слишком сложная схема для простой системы, состоящей
из мальчика, собаки и мяча. Более того, на ней недостает некоторых
линий – нам следовало бы добавить еще три связи между фактами,
содержащими "1" и три связи между фактами, содержащими
"2", доведя их общее число до 18. Чтобы сделать схему менее
громоздкой, добавим к ней вершины, вынеся идентификаторы из
(рис 11.2) Упрощенный граф связей между кортежами.Наш подход – выделение элементов из
(рис 11.3) Значительно упрощенный граф связей между кортежами.Наконец, мы можем заметить, что каждый предикат имеет ровно одну входящую и одну исходящую стрелки. Поэтому мы можем превратить предикаты в именованные стрелки (ребра), освободив граф от избыточных узлов (вершин). Результат этой процедуры показан на рисунке 11.4, на котором также изменено расположение некоторых элементов.
(рис 11.4) Граф связей между кортежами в нотации RDF.На этом рисунке ясно видны отношения, выражаемые предикатами, и их характер. Существуют второстепенные предикаты, которые служат лишь для описания идентификаторов (имя, цвет, тип), и более важные предикаты (хозяин, играет-с), содержащие информацию об отношениях между интересующими нас идентификаторами. Таким образом, решения использовать идентификаторы для каждого моделируемого объекта реального мира (см. листинги 11.1 и 11.2) и выделить идентификаторы на схеме (см. рисунок 11.2) оказались продуктивными. Как мы видим, идентификаторы играют важнейшую роль в построении компактной и выразительной схемы.
Граф на рисунке 11.4 соответствует официальной нотации
Данные
Наконец, существует третий способ организации фактов, часто
используемый в
Контейнер представлен на схеме

(рис 11.6) Граф RDF, на котором сходные термы объединены при помощи линии.(рис 11.5) Граф RDF, на котором сходные термы объединены при помощи контейнера.Контейнеры представляют собой простой механизм структурирования
данных. Они также поддерживают запросы к коллекциям фактов.
Разработчик приложения может использовать контейнер в качестве
частичного индекса,
Итак, факты могут храниться в виде простого набора триплетов или
сложного графа, организованного вокруг идентификаторов. Между этими
полюсами находится частичная структура, задаваемая контейнером,
которую можно сравнить с маршрутом, нарисованным на карте. Набор
фактов называется хранилищем фактов. Сложные хранилища фактов
называются
Факты могут описывать другие факты. В некоторых особых ситуациях это следует иметь в виду, но в большинстве случаев полезнее игнорировать такую возможность. Некоторые базовые сведения о фактах, описывающих факты, приведены в этом разделе. Факты, зафиксированные в примере с мальчиком и собакой, неявно подразумевают множество других фактов, которые могут быть выражены в явном виде. Некоторые из них следуют из устройства нашей маленькой коллекции фактов, другие истинны почти автоматически. Все следующие примеры основаны на единственном факте:
<- 1, имя, Том ->
Одна из групп дополнительных фактов, следующих из устройства коллекции, – информация о типах. Программист, разрабатывающий коллекцию фактов, может решить хранить в ней типизированные данные. Например, следствием единственного факта, указанного выше, могут быть следующие факты:
<- 1, тип, integer -> <- Том, тип, string ->
Эти факты указывают типы для субъекта и объекта ранее приведенного
факта. Они содержат дополнительную информацию о другом факте и
являются аналогом словаря данных или
Здесь уместно повторить сказанное в начале этой лекции. Многие
специалисты называют информацию такого рода метаданными.
Предполагается, что этот термин позволяет разграничить информацию (в
данном случае – содержание web-документа, на который указывает URL) и
"информацию об информации" (описание документа и самого
URL), которая и называется метаданными. На практике, если программист
пишет код для работы с файлом закладок, единственной интересной для
него информацией являются так называемые метаданные – содержание этого
файла. С его точки зрения метаданные оказываются данными, с которыми
он должен работать. То, что для одного человека является метаданными,
для другого – просто данные. Таким образом, при изучении
Говоря коротко, термин "метаданные" часто используется
без необходимости. С точки зрения программиста единственным элементом
Следующие три факта являются истинными автоматически:
<- пример-факта, субъект, 1 -> <- пример-факта, предикат, имя -> <- пример-факта, объект, Том ->
Здесь пример-факта означает факт, приведенный в начале этого
раздела. Первый из трех фактов (с предикатом субъект) утверждает, что
субъектом исходного факта является 1. Согласно второму факту,
предикатом исходного факта является имя. Иными словами, все это факты
об исходном факте. Процесс построения таких фактов называется
Реификация сходна с извлечением метаданных, однако потенциально
ведет к гораздо более запутанным следствиям. Рассмотрим, например,
следующую проблему. Как было сказано выше, все существующие
(зафиксированные) факты считаются истинными, а все прочие – ложными.
Можем ли мы утверждать, что исходный факт (пример-факта) имеет
субъект, если не сформулирован первый из фактов
Еще одна группа фактов, которые можно сформулировать на основе существующих фактов, связана с именами. Разработчик, формирующий группу фактов, может пожелать дать имена элементам этих фактов. Используя все тот же пример, можно присвоить имена субъекту или объекту, подобно тому, как даются имена полям записи в базе данных, или король жалует дворянские титулы своим подданным:
<- 1, имя, идентификатор-лица-> <- Том, имя, имя-лица-> <- пример-факта, имя, определение-лица->
Эта процедура тоже создает возможности для путаницы. Исходный факт утверждает, что существует лицо по имени Том. Однако согласно первому из приведенных здесь фактов, строка "Том" имеет имя (тип) имя-лица, а исходный факт в целом – "существует лицо по имени Том" – имеет имя определение-лица. Итак, имя Тома – "Том", но оно, в свою очередь имеет имя имя-лица. Все эти тонкости не имеют практического значения для большинства разработчиков.
Наконец, следует отметить, что большинство аспектов многих подходов к моделированию данных могут быть выражены при помощи фактов с предикатами. Например, при помощи следующих предикатов можно формулировать факты, описывающие объектно-ориентированную модель:
является-подклассом имеет использует является-экземпляром
А этот набор предикатов может использоваться для описания реляционной модели:
имеет-ключ имеет-внешний-ключ один-ко-многим один-к-одному имеет-необязательный
С помощью подобных предикатов можно надстраивать сложные слои
семантики (например, объектную модель) над базовой системой простых
фактов. Однако это сложный процесс, с которым вряд ли справится
начинающий разработчик. Некоторые возможности такого рода
предусмотрены в самом языке
Наконец, новые факты могут быть выведены из существующих. В примере с мальчиком и собакой следующий факт может рассматриваться как следствие сформулированных фактов:
<- Том, играет-с, Спот->
Следует ли рассматривать его как следствие, зависит от правил
вывода и других допущений, принятых в конкретной системе. В конце
концов, если мальчик и собака играют с одним и тем же мячом, они,
вероятно, играют друг с другом. Вывод таких фактов является функцией
дедуктивных систем. Mozilla не выполняет
Факты, собранные вместе для обработки, содержатся в хранилище фактов. Последнее является аналогом базы данных применительно к фактам и, как правило, находится в оперативной памяти, а не на диске.
Подводя итоги этого введения, отметим, что триплеты с предикатом
представляют собой полезное подмножество простых
Хранилище фактов не имеет практического смысла, если нет возможности извлекать из него факты. Разработчику необходим способ получать нужные факты, игнорируя остальные.
По документам getElementById(),
или более сложных технологий, таких как XML Query или
Вместо этого документы grep(1).
Системы запросов не рассматриваются подробно в этой лекции, однако они основаны на концепции определенного факта. Определенный факт (иногда называемый конкретным фактом), представляет собой полностью известный факт. Все факты, обсуждавшиеся в этой лекции до настоящего момента, были определенными фактами.
В качестве примера рассмотрим следующее высказывание: "Том –
хозяин
<- Том, хозяин, Спот ->
Мы можем сформулировать и другое высказывание: "Том владеет собакой". Эквивалентный факт можно записать как:
<- Том, хозяин, собака ->
Однако если принять во внимание, что в мире существует множество собак, нужно сделать вывод, что данное высказывание не позволяет ответить на вопрос "Какой собакой владеет Том?" В этом случае высказывание "Том владеет собакой" является неопределенным, поскольку оно не позволяет однозначно установить объект (конкретную собаку). Адвокат мог бы сказать: "Это утверждение необоснованно, поскольку вы не можете указать конкретную собаку, которой владеет Том". Таким способом он подчеркнул бы, что ваше высказывание слишком туманно, чтобы быть истинным. Лучший факт, который мы можем записать в такой ситуации, имеет следующий вид:
<- Том, хозяин, ??? ->
Знаки вопроса не являются какой-либо специальной синтаксической конструкцией, они лишь указывают на неопределенный объект. Вы вряд ли сможете сделать что-либо с таким неопределенным фактом, представляющим собой противоположность определенному.
Однако если компьютер, в отличие от вас, знает, какая собака принадлежит Тому, вы можете передать неполный факт компьютеру в качестве запроса. Компьютер, исполняя соответствующую программу, может сопоставить неполный факт (называемый целью) со всеми зафиксированными фактами и возвратить лишь те факты, которые согласуются с ним. Этот процесс называется унификацией, в реализации Mozilla он представляет собой простое сопоставление с образцом. Таким образом вы найдете всех собак, принадлежащих Тому, или всех животных, принадлежащих Тому, или вообще все, что принадлежит Тому. То, что вы получите в ответ, зависит от того, какие факты содержатся в хранилище фактов. В любом случае, системы запросов и фильтрации Mozilla выполнят необходимые действия.
Разработчик осуществляет поиск или фильтрацию определенных фактов
Подводя итоги, отметим, что факты могут храниться подобно данным и извлекаться при помощи системы сопоставления цели с определенными данными.
Синтаксис
Разумеется, наиболее важными из них являются стандарты
(спецификации), относящиеся собственно к
На первом этапе стандартизации
http://www.w3.org/TR/1999/REC-rdf-syntax-19990222.
"Окончательная рекомендация по модели и синтаксису
http://www.w3.org/TR/2000/CR-rdf-schema-20000327. Этот документ
разрабатывался в течение нескольких лет. Он определяет схему
Второй этап стандартизации
http://www.w3.org/TR/rdf-syntax-grammar/, "Спецификация
синтаксиса
http://www.w3.org/TR/rdf-schema/, "Язык описания словаря
Существует также ряд пояснительных документов, посвященных
различным аспектам
Из перечисленных спецификаций Mozilla практически полностью реализует первый документ (рекомендацию 1999 г.) и некоторые новые возможности, введенные третьим документом (пересмотренной рекомендацией).
Другие стандарты, тесно связанные с
Эти стандарты предлагают способ описания фактов при помощи тегов XML. Субъекты и объекты фактов могут быть представлены атрибутами тегов или (в случае объектов) текстовыми узлами, заключенными в теги. Однако стандарты определяют лишь небольшое количество конкретных тегов. Предполагается, что дополнительные теги и атрибуты определяются разработчиком конкретного приложения.
Эти дополнительные имена образуют словарь, который может быть
формально описан в документе
Mozilla не использует
Документ
http://www.w3.org/1999/02/22-rdf-syntax-ns#
Файлы с документами
text/rdf text/xml
Однако версия 1.4 еще не поддерживает официального типа
application/rdf+xml
Основная цель
<факт субъект="..." предикат="..." объект="..."/> <факт> <субъект .../> <предикат .../> <объект .../> </факт> < субъект ... предикат="..." объект="..."/>
Однако в
<факт субъект="..."> <предикат>объект</предикат> </факт>
Эта запись отражает лишь общую концепцию синтаксиса
<Description about="http://www.mozilla.org/"> <NC:LastVisited>10 января 2004</NC:LastVisited> </Description>
Такой синтаксис допускает вложение одних фактов в другие. Он может
служить основой для нескольких видов сокращенной записи и сходен с
некоторыми web-технологиями. К сожалению, терминология
При разработке
| Термин, относящийся к фактам | Термин |
Термины web-технологий, повлиявшие на терминологию |
Синтаксис |
|---|---|---|---|
| Факт | Описание | Описание документа или запись | <Description>, <Seq>, <Alt>, < |
| Субъект | Ресурс | URL | about=, id= |
| Предикат | Свойство (и ресурс) | Свойство объекта, свойство CSS, атрибут XML | Определяется пользователем |
| Объект | Значение (или ресурс) | Значение свойства, значение атрибута | resource=, простой текст |
На практике полезно комбинировать оба подхода. С общей точки
зрения,
В качестве примера рассмотрим уже встречавшийся нам простой тег <Description> определяет субъект факта (на который
указывает атрибут about этого тега). Если тег имеет содержимое, оно
представляет прочие <NC:LastVisited> представляет
собой предикат, а его содержимое, простая строка "10 января
2004", – объект. В терминологии <Description> определяет ресурс.
Этот ресурс может иметь свойства, выраженные другими тегами. Тег <NC:LastVisited> – одно из таких свойств, значением которого
является "10 января 2004".
Терминология
Вот полный список основных тегов
<RDF> <Description> <Seq> <Bag> <Alt> <li>
Последние четыре тега являются избыточными – эквивалентные им
конструкции могут быть выражены при помощи тега <Description> –
так что
<Statement> <subject> <predicate> <object>
Эти теги предназначены для <Statement>
используется для
<, <Seq> или <Alt>, а также тегов <li>, в которые заключаются элементы
контейнера. Контейнер вместе со своим содержимым образует коллекцию.
Эта коллекция может быть помещена вместо объекта какого-либо факта.
Контейнер выглядит следующим образом:
<Description>
<Bag>
<li>объект 1</li>
<li>объект 2</li>
<li>объект 3</li>
</Bag>
</Description>
В обычном факте между объектом и субъектом (или между ресурсом и
значением свойства) существует отношение "один к одному". У
каждого объекта есть один субъект. В случае контейнеров отношение
между фактом и объектом имеет вид "один ко многим", причем
минимально возможное число объектов у субъекта равно нулю. Контейнеры
Одно из возможных применений контейнера – поддержка списка
свободных мест в системе заказа билетов. Каждое место является
ресурсом; в системе должно быть отражено состояние всех мест – как
свободных, так и зарезервированных. Список свободных мест может быть
организован отдельно от фактов о состоянии конкретных мест при помощи
контейнера. Соответствующий фрагмент
<Description>
<Description id="место:A1">
<крайнее>true</крайнее>
</Description>
<Description id="место:A2">
<зарезервировано>Тим</зарезервировано>
<крайнее>false</крайнее>
</Description>
<Description id=" место:A3">
<крайнее>false</крайнее>
</Description>
<Description id=" место:свободные">
<Bag>
<li resource="место:A1"/>
<li resource="место:A3"/>
</Bag>
</Description>
В этом фрагменте для каждого места указано, является ли оно крайним
(у прохода) и в том случае, если место не свободно, имя того, кто его
зарезервировал. Синтаксис место: относится к воображаемой < содержит ссылки на два свободных
места. Синтаксис тегов <li> в этом примере – один из способов
сокращения, допустимых языком
Таким образом, контейнеры могут использоваться для того, чтобы
предоставить программисту доступ к подмножествам фактов. Элементы
контейнера указывают на субъекты подмножества какого-либо множества
фактов, описанных за пределами контейнера. Просматривая контейнер,
можно получить доступ к этим фактам. Контейнеры могут рассматриваться
как простая структура данных для фактов и как простой механизм
навигации. В системе заказа билетов программист может зарезервировать
место, выбрав его из контейнера со свободными местами, добавив
вложенный тег (предикат) <зарезервировано> к соответствующему
тегу <Description>, а затем удалив место из контейнера.
В объектно-ориентированной терминологии контейнер "использует" объекты – члены коллекции. Контейнер содержит лишь ссылки на них, а не сами объекты.
Теги-контейнеры и соответствующие коллекции всегда могут быть заменены эквивалентной конструкцией из простых фактов. Об этом рассказано в описании отдельных тегов.
В примере с мальчиком и собакой мы стремились снабдить каждый
элемент, моделируемый при помощи фактов, идентификатором. В отличие от
многих других приложений XML, в
Первый способ использования идентификаторов – обозначение целого
факта. Для этого к тегу, выражающему данный факт, добавляется атрибут id. URL документа id
какого-либо факта из данного документа, является уникальным
идентификатором факта в глобальном масштабе. Согласно документу <A> без
атрибута HREF, на которые ссылается часть URL после символа #,
маркируют лишь определенное место в едином документе-ресурсе. Вот
пример идентификатора
<Description ID="printEnabled" ... />
Возможно, этот файл содержит информацию о состоянии подсистемы
печати, и атрибут ID позволяет обратиться к конкретному факту,
используя осмысленное имя.
Второй способ использования идентификаторов в
Однако такая непосредственность не обязательно должна иметь место.
Так, на том же листинге записано несколько фактов о Томе. При этом сам
Том – реальный мальчик – не присутствует в этих фактах
непосредственно. Вместо этого мы используем число (1), имея в виду,
что в данной группе фактов оно представляет Тома. :)
или URL web-документа, содержащего запись о Томе. Любой факт,
субъектом которого является строка, совпадающая с этим URL, является
фактом о Томе. В терминологии web-разработчика Том является ресурсом,
на который указывает URL.
Однако
Примечательно, что id, значением которого должен быть
корректный URL. Для удобства чтения URL предиката как правило содержит
слово, поясняющее его общий смысл, например http://www.example.com/#Owner
(владелец).
Таким образом, при необходимости факты можно выражать при помощи
одних лишь идентификаторов-URL. Фактически такие идентификаторы
являются указателями на
Здесь, однако, существует одна сложность. Любой URL в документе
Строго говоря, идентификаторы, заменяющие
<Description> или
контейнер не имеют идентификатора. Это факты с неопределенным
субъектом или анонимные факты. Документ <Description> без
идентификаторов.
Тег < является
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
Для этого тега не определено никаких специальных атрибутов. В нем
могут встречаться лишь декларации пространств имен XML, добавляющие
словари (дополнительные наборы тегов) для использования в документе.
Эти декларации играют ту же роль, что и указание
| URL пространства имен | Префикс xmlns | Где определено | Использование |
|---|---|---|---|
| http://www.w3.org/1999/02/22-rdf-syntax-ns# | |
http://www.w3.org | Базовая поддержка |
| http://home.netscape.com/WEB-rdf# | Web |
Код Mozilla | Закладки и метки времени |
| http://www.mozilla.org/rdf/chrome# | |
Код Mozilla | Управление пакетами |
| http://home.netscape.com/NC-rdf# | nc |
Код Mozilla | Общего назначения |
| http://www.mozilla.org/LDAPATTR-rdf# | ldapattr |
JavaScript, на основе свойств |
Поддержка |
| http://www.mozilla.org/inspector# | |
JavaScript | Инспектор DOM |
За исключением первой строки таблицы, ни одному из указанных URL не
соответствует реальный документ. URL, содержащие "netscape",
являются наследием Netscape Communicator 4.x. Префиксы представляют
собой рекомендации, основанные на существующих соглашениях. Из
перечисленных префиксов в различных компонентах Mozilla наиболее
широко используются web, и nc. Чтобы использовать пространство
имен, нужно знать ключевые слова (теги), предоставляемые этим
пространством. Эти ключевые слова обсуждаются ниже в разделе
"Теги предикатов". Разработчик приложений может добавлять к
Содержимым тега < являются теги-потомки. Его
непосредственными потомками могут быть тег <Description> и теги-
контейнеры <Seq> <.
Тег <Description> является основой всего языка <Description>. В
листинге 11.8 представлены два факта, выраженные с помощью одного тега <Description>.
<факт субъект="..."> <свойство1 ...>объект1</свойство1> <свойство2 ...>объект2</свойство2> </факт>
Этот фрагмент записан на псевдокоде, а не на синтаксически
корректном
В < из этого примера играет тег <Description>, который по сути является контейнером. Он, однако,
отличается от прочих контейнеров
Тег <Description> имеет следующие специальные атрибуты.
ID about type
Каждый тег <Description> должен иметь атрибут ID или атрибут about. Если тег не имеет ни одного из этих атрибутов, считается, что
соответствующий факт имеет анонимный субъект. Этот субъект для
внешнего мира невидим (для него невозможно определить уникальный URL),
а в рамках данного документа он считается неопределенным
Считается, что атрибут ID имеет имя, которое совпадает с его
значением. Это имя можно добавить к URL документа ID тега <Description> имеет смысл в том случае, если у этого
тега есть ровно одно свойство. Субъект факта, определенного с
использованием атрибута ID, доступен для внешнего мира (как и в
предыдущем абзаце, речь идет не о физической доступности документа, а
о возможности адресации факта и его субъекта).
Атрибут about определяет субъект факта. Его значением должен быть
полный URL. Если атрибут about используется вместо атрибута ID, факт
как целое не имеет собственного URL и недоступен из внешнего мира.
Атрибут type указывает тип объекта факта (в терминологии type в документах type ;
атрибут type может рассматриваться как сокращенная запись этого
предиката.
Mozilla не поддерживает следующие специальные атрибуты тега <Description>:
aboutEach aboutEachItem bagID
Два первых атрибута не рекомендованы к применению последними
версиями спецификации bagID используется для
Тег <Description> и его содержимое могут быть записаны как
единственный тег <Description> без всякого содержимого. Это
можно сделать, записав предикат и объект как атрибут XML тега <Description> и значение этого атрибута соответственно.
Следующий фрагмент
<Description about="www.test.com/#Том"> <ns:Владелец>Спот</ns:Владелец > </Description>
В данном случае субъект и предикат представлены с помощью URL; объект представлен с помощью литерала. Предикат принадлежит пространству имен XML с префиксом ns. Это пространство было декларировано в начале документа, поэтому полный URL предиката нельзя установить на основании одного лишь данного фрагмента. Сокращенная запись того же фрагмента выглядит следующим образом:
<Description about="www.test.com/#Том" ns:Владелец="Спот"/>
Обратите внимание на префикс пространства имен перед атрибутом. Эта
возможность предусмотрена спецификацией XML, но не слишком часто
используется на практике. Сокращенная запись допустима лишь в том
случае, когда объект/значение является литералом, а не
Предикаты или свойства определяются разработчиком конкретного
приложения. Лучше всего найти уже разработанный набор тегов,
подходящий для конкретной цели. Разумеется, можно придумывать и
собственные теги в процессе разработки. Однако использование корректно
определенного пространства имен является признаком культуры
разработчика и того, что он продумал назначение своих данных,
представляемых в формате
превращает
любой тег в элемент-наблюдатель. Доступны следующие специальные
атрибуты:
ID parseType
Атрибут ID имеет то же назначение, что и в теге <Description>. Если родительский тег <Description>
содержит более чем один тег-предикат (т.е. представляет несколько
фактов), атрибут ID может быть добавлен к тегам-предикатам, чтобы
однозначно идентифицировать отдельные факты.
Атрибут parseType является указанием для синтаксического
анализатора type, обсуждаемого в
следующем разделе, и указывает, каким образом должна
интерпретироваться текстовая строка, представляющая значение/объект.
Атрибут parseType может принимать следующие значения:
Literal Resource Integer Date
Два первых значения предусмотрены спецификацией –
значение атрибута по умолчанию, оно подразумевает, что значение
является произвольной строкой. Resource означает, что строка значения
представляет Integer и Date являются дополнениями
Mozilla и указывают, что строка должна интерпретироваться как 32-битное
целое со знаком и как дата соответственно. Предполагается, что
дата может быть в любом из нескольких форматов, однако не все из них
поддержаны полностью. Самый надежный вариант – использовать формат
date(1), но в полученной строке заменить
"Date не должно содержать символов Unicode, выходящих за
пределы набора ASCII.
В type, соответствующий атрибуту type тега <Description>. Использование этого атрибута является сокращенным
вариантом следующей записи:
<rdf:type>value</rdf:type>
В данном случае является префиксом пространства имен
Пространства имен, перечисленные в таблице 11.3, также обеспечивают дополнительные наборы предикатов. Поскольку предикаты, по сути, являются элементами данных, сами по себе эти имена ничего не "делают".
В лекции 9 "Команды" было сказано, что платформа Mozilla
определяет множество команд, но все они связаны с тем или иным
приложением – Навигатором, Компоновщиком или
Полного списка этих предикатов не существует ни в документации, ни
даже в исходном коде. Чтобы ввести новый предикат, разработчику
достаточно добавить его в файл
Вновь создаваемое приложение на платформе Mozilla должно иметь
формально описанную
Существующим схемам данных нужно строго следовать лишь в том
случае, когда приложение должно создавать или изменять файлы
Теги-предикаты могут иметь атрибут resource. Он аналогичен атрибуту
about тега <Description>, но указывает на объект факта (значение
свойства). При использовании атрибута resource тег-предикат может не
иметь содержимого XML, а значением атрибута resource должен быть не
литерал, а корректный
<ns:Владелец parseType="Resource">www.test.com/#Spot</ns:Владелец>
Тогда ее сокращенная форма имеет следующий вид:
<ns:Владелец rdf:resource="www.test.com/#Spot"/>
Это применение атрибута resource не представляет трудностей для
понимания. Однако данный атрибут имеет и более сложное применение.
В простом случае, рассмотренном только что, значение атрибута resource участвует лишь в одном факте, на объект которого оно
указывает. Однако этот же объект может быть субъектом другого факта. В
данном случае применимо следующее весьма запутанное правило: если в
теге-предикате встречается атрибут resource, а также другие пары
атрибут-значение, эти пары интерпретируются так же, как если бы они
принадлежали тегу <Description>, субъектом которого (значением
атрибута about ) был бы resource
тега-предиката. Иными словами, внутри тега-предиката одного факта
могут быть определены другие, вложенные факты, причем объект
объемлющего факта является субъектом вложенных фактов.
Все это весьма сложно и запутанно, и не стоит тратить усилий на
изучение всех тонкостей, если только вы не разрабатываете сложное и
амбициозное приложение. Этот вариант сокращенной записи был предложен
для того, чтобы уменьшить количество вложенных тегов в документе
<Seq>, < и <Alt> – три тега-контейнера
<Seq> представляет собой
< представляет собой простую коллекцию элементов без
каких-либо ограничений на ее состав.
<Alt> подразумевает список альтернатив. Это простая коллекция
без ограничений, однако подразумевается, что все ее элементы являются
альтернативами в смысле, зависящем от конкретного приложения. Так, в
контейнере <Alt> могут содержаться варианты одного и того же
сообщения программы на разных языках.
Эти контейнеры позволяют организовывать субъекты и объекты в группы, а также компактно записывать несколько сходных фактов. В контейнерах всех трех типов могут встречаться повторяющиеся элементы.
Контейнеры содержат элементы, каждый из которых заключен в тег <li>, подобно элементам списков <UL> и <OL> в языке
HTML. Каждый элемент контейнера является объектом. Поскольку объект в
<Description>,
контейнеры могут быть вложенными. В листинге 11.9 приведен пример
простого контейнера.
<Description about="www.example.com/#Том">
<ns:Владелец>
<Bag ID="Собаки">
<li>Спот</li>
<li>Фидо</li>
<li>Цербер</li>
</Bag>
</ns:Владелец>
</Description>
Смысл этой записи прозрачен: Том – владелец
<- "www.example.com/#Том", ns:Владелец, "Собаки" -> <- "Собаки", rdf:_1, "Спот" -> <- "Собаки", rdf:_2, "Фидо" -> <- "Собаки", rdf:_3, "Цербер" ->
<Description>, этот
Однако для того, чтобы этот подход мог работать, необходимо решить две проблемы. Во-первых, новому субъекту требуется идентификатор или, по крайней мере, соответствующий ему литерал. Кроме того, у вновь создаваемых фактов, помимо субъекта и объекта, должны быть также предикаты (имена свойств).
Первая проблема решается просто – создатель документа должен
снабдить тег-контейнер атрибутом ID или about. В противном случае
контейнер будет анонимным, а документ
Вторая проблема решается в процессе интерпретации документа _1, _2, _3. Поскольку эти имена относятся к пространству
имен , и т.д., при условии, что
префикс присвоен этому пространству имен. Таково происхождение
предикатов, использованных в листинге 11.10.
в листинге 11.11 представлены факты, эквивалентные записи в
листинге 11.9 (т.е. порождающие в хранилище фактов ту же структуру при
интерпретации документов
<Description about="www.test.com/#Том"> <ns:Владелец resource="Собаки"/> </Description> <Description about="Собаки" rdf:_1="Спот"/> <Description about="Собаки" rdf:_2="Фидо"/> <Description about="Собаки" rdf:_3="Цербер/>
Для факта с предикатом < использована сокращенная
запись, поскольку объектом является литерал. Мы не можем использовать
аналогичную форму записи для первого факта, поскольку его объект,
"Собаки", в данном случае рассматривается как фрагмент URL,
а не как литерал. Использовать или не использовать контейнеры – выбор
разработчика, однако они, как правило, выглядят аккуратнее, чем
эквивалентный набор тегов <Description>.
Все эти факты хранятся во внутреннем представлении документа
Тег-контейнер может иметь следующие атрибуты:
ID type
Атрибут ID аналогичен тому же атрибуту тега <Description>.
Значение атрибута type не определяется автором документа. Оно
автоматически устанавливается равным имени тега-контейнера (например, ), которое и считается типом данного тега. Эта пара
атрибут-значение образует отдельный факт, субъектом которого является значение
атрибутов about или ID тега-контейнера. Однако считается, что
предикатом этого факта является не type, а специальное значение instanceOf. В примере с тремя собаками этот факт имеет следующий
вид:
<- "Собаки", http://www.w3.org/1999/02/22-rdf-syntax-ns#instanceOf, http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag ->
С помощью данного факта разработчик приложения может определить контейнер и установит его тип. Однако в случае Mozilla необходимости в этом, как правило, не возникает, поскольку платформа предоставляет удобные вспомогательные объекты.
В тегах-контейнерах также может использоваться та же общая форма
сокращенной записи "свойство = значение", что и в теге <Description>. Для тега <li> определены следующие
атрибуты:
parseType resource
Они аналогичны соответствующим атрибутам тегов-предикатов и допускают те же формы сокращенной записи.
На этом мы заканчиваем обсуждение синтаксиса
В этом разделе представлено несколько примеров практического
применения
Менеджер загрузок классического браузера представляет собой
наглядный пример использования документа Навигатор
| Загрузки диалогового окна настроек Mozilla ( пункт меню Правка |
Настройки ).
Интерфейс Менеджера загрузок состоит из единственного окна XUL, а
данные о загрузках хранятся в файле Файл | Сохранить как. Кроме того,
Менеджер загрузок можно открыть в любой момент при помощи пункта меню Инструменты | Менеджер загрузок. Файл <tree>.
Чтобы пронаблюдать работу программы с файлом <Seq>, как
показано в листинге 11.12.
<?xml version="1.0"?> <RDF:RDF xmlns:NC="http://home.netscape.com/NC-rdf#" xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > <RDF:Seq about="NC:DownloadsRoot"> </RDF:Seq> </RDF:RDF>
Затем откройте любую страницу на удаленном сервере, например
http://www.mozilla.org. Сохраните страницу в локальном файле и, когда
сохранение будет полностью завершено, перезагрузите файл downloads.<Description> с содержимым, а также элемент коллекции <Seq>. Тег <Description> содержит восемь фактов о
загруженном файле. Примечательно, что эти факты записаны с помощью
различных видов нотации. Субъект факта с тегом <Description>
одновременно является объектом в коллекции <Seq>. Эта коллекция
позволяет найти все записи о файлах, включенные в документ.
Файл downloads.
<?xml version="1.0"?>
<RDF:RDF
xmlns:NC="http://home.netscape.com/NC-rdf#"
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
<RDF:Seq about="NC:DownloadsRoot">
<RDF:li resource="C:\tmp\test_save.html"/>
</RDF:Seq>
<RDF:Description about="C:\tmp\test_save.html"
NC:Name="test_save.html"
NC:ProgressMode="none"
NC:StatusText="Finished"
NC:Transferred="1KB of 1KB">
<NC:URL resource="http://www.mozilla.org/"/>
<NC:File resource="C:\tmp\test_save.html"/>
<NC:DownloadState NC:parseType="Integer">1</NC:DownloadState>
<NC:ProgressPercent NC:parseType="Integer">100</NC:ProgressPercent>
</RDF:Description>
</RDF:RDF>
При использовании Microsoft Windows локальные пути записываются с
префиксом C: (или другим именем диска). Это расширение синтаксиса URL,
используемое компанией Microsoft, поддерживается Mozilla. Такая запись
эквивалентна префиксу file:///C| / и, с точки зрения Mozilla, допустима
в составе URL.
Попробуйте сохранять другие страницы, наблюдая изменения в файле.
Также можно, закрыв окно Менеджера загрузок, аккуратно удалить из
файла один из элементов контейнера <Seq> и соответствующий тег <Description>. Затем следует вновь открыть окно и посмотреть на
результат.
Менеджер загрузок мог бы быть реализован без использования
Выше мы уже обсуждали некоторые типы, используемые в документах
Типы литералов: . Тип XMLLiteral не поддерживается.
Типы компонентов фактов: Property, . Тип List не
поддерживается.
Типы фактов: тип Statement не поддерживается.
Типы, используемые для , и object
не поддерживается.
Тип используется для хранения массива бинарных данных. Этот
тип нельзя указать из скрипта JavaScript – это расширение Mozilla,
которое может быть использовано только из кода на C/C++. Литералы типа используются, в частности, в
Типы, поддерживаемые в документах type тега <Description>, что эквивалентно использованию
встроенного тега-предиката <.
Платформа Mozilla не поддерживает типов
До сих пор при обсуждении идентификаторов в этой лекции мы
использовали в качестве примеров только URL. Этот формат
идентификатора полезен при хранении информации о web-сайтах и других
ресурсах Internet. Однако если приложение должно работать с простыми
данными, вместо URL рекомендуется использовать
Строго говоря, идентификаторы в
URL связывает ресурс с точкой доступа к нему (адресом) и методом
доступа, например протоколом HTTP. Ресурс, доступный по указанному
адресу, например web-страница, может меняться со временем.
С точки зрения программиста,
urn:{namespace}:{name}
Как {namespace}, так и {name} представляют собой строку. Строка {namespace} не может иметь значения "{name} может содержать любые символы ASCII,
включая двоеточие, что поначалу может показаться странным. Точный
синтаксис {name}
может также содержать знаки пунктуации и тоже нечувствительно к
регистру. Существуют некоторые ограничения на допустимые знаки
пунктуации. {name} является необязательной. Вот два примера корректных
urn:myapp:runstate urn:myapp:perfdialog:response
Во втором {name} выглядит так, как если бы она содержала
второе пространство имен, вложенное в первое, и собственно имя. С
точки зрения формального синтаксиса это лишь видимость – перед нами
обычное имя, содержащее символ двоеточия. Однако программисты могут
использовать этот пример для того, чтобы упорядочить большое
количество
Вот пример факта, записанного на языке
<Description about="urn:mozilla:skin:modern/1.0" chrome:author="mozilla.org"/>
Здесь : представляет собой префикс пространства имен XML,
"mozilla.org" – литерал, а "
mozilla["skin:modern/1.0"].author = "mozilla.org";
Или, чуть более подробно:
urn.mozilla.skin["modern/1.0"].chrome.author = "mozilla.org";
Разумеется, факт в общем случае не сводится к операции присваивания, так что эти примеры отражают лишь один из возможных способов интерпретации приведенного факта.
Существует специальная "data:" ), предназначенная для представления
обычных данных в виде URL и описанная в документе
Типы Правка | Настройки | Навигатор |
Вспомогательные приложения.
Как и Менеджер загрузок, система настройки типов pref-application.
Эту подсистему Mozilla можно изучать так же, как и Менеджер
загрузок. Разница между ними в том, что
urn:mimetypes urn:mimetypes:root urn:mimetypes:text/plain urn:mimetypes:application/octet-stream urn:mimetypes:handler:text/plain urn:mimetypes:handler:application/octet-stream urn:mimetypes:externalApplication:text/plain urn:mimetypes:externalApplication:application/octet-stream
Поскольку
Как и в случае с Менеджером загрузок, вся информация о типах
находится в контейнере <Seq>, который обеспечивает легкий доступ
к ней. Если одновременно открыто несколько окон браузера и загружается
содержимое различных типов, все эти окна пользуются одним и тем же
источником данных
Mozilla использует технологии
Согласно спецификации
Наиболее известным результатом деятельности в этом направлении
является так называемое "Дублинское ядро" (
Еще одна область применения
В реальности существует целый ряд механизмов "управления
содержимым" в указанном смысле, и
Область, в которой
Пока
На этом мы заканчиваем обсуждение примеров применения
Это практическое занятие посвящено процессу моделирования,
результатом которого является набор фактов
Мы много экспериментировали с интерфейсом NoteTaker и скриптами
JavaScript, однако пришло время заняться проектированием. У нас до сих
пор нет ясного понимания того, какими данными должен манипулировать
NoteTaker. Мы выбираем
На платформе Mozilla
Выбор фактов в качестве
При разработке и реализации
Как правило, при моделировании данных приходится предпринять несколько попыток, прежде чем будет найден оптимальный вариант. Мы, однако, сразу же начнем с приемлемого подхода, обращая в процессе моделирования внимание на некоторые распространенные ошибки и тупиковые направления.
Мы можем без труда описать
Ключевые слова – обычные слова, добавляемые пользователем для характеристики URL, к которому относится заметка. Если два ключевых слова были использованы для описания одной заметки, говорят, что эти слова связаны. Эта связь имеет значение и за пределами конкретной заметки – тот факт, что они появились вместе в каком-либо контексте, указывает на то, что эти слова связаны в широком смысле. Связи между ключевыми словами могут использоваться для контекстно-зависимой подсказки пользователю. Когда последний выбирает ключевое слово для заметки, одновременно отображается список всех слов, связанных с выбранным. Пользователь может отметить некоторые слова в этом списке, чтобы присвоить их заметке одновременно с первым.
В приложение NoteTaker, которое разрабатывается в этой книге, будет
включен лишь минимум функциональности, связанной с ключевыми словами,
для демонстрации некоторых приемов работы с XUL и
Интерфейс NoteTaker включает еще два элемента данных, которые отображаются как флажки "Отбросить запрос" и "Корневая страница" в диалоговом окне редактирования заметки. Эти данные не являются свойствами заметки, а скорее управляют процессом ее создания.
Если установлен флажок "Отбросить запрос", то из URL новой заметки будет удалена любая информация, относящаяся к запросу GET. Например, этот URL
http://www.test.com/circuits.cgi?voltage=240V;amps=50mA
будет сокращен до следующего
http://www.test.com/circuits.cgi
При этом вновь созданная заметка будет появляться при просмотре любой страницы, чей URL начинается с этой сокращенной строки. Если установлен флажок "Корневая страница", то URL будет сокращен еще больше, до
В этом случае заметка будет соответствовать всем страницам данного сайта. Если URL содержит каталог отдельного пользователя, как в примере:
http://www.test.com/~fred/mytests/test2.htm
то при установленном флажке "Корневая страница" он будет сокращен
При использовании любого из этих вариантов при просмотре
конкретного URL будет отображаться только наиболее специфичная для
него заметка. Иными словами, если одновременно определены заметка для
корневой страницы сайта и заметка для другой его страницы, то при
просмотре этой страницы будет отображаться лишь последняя заметка. В
любом случае, наличие этих флажков никак не влияет на
На этом выполнение первого этапа нашего плана завершено, и мы можем
перейти ко второму. В результате процесса моделирования все наши
данные должны быть представлены в виде фактов-триплетов. Пока же мы
должны выбрать из описания значимые термины, которые в дальнейшем
станут
заметка ключевое-слово URL аннотация подробности сверху слева высота ширина
Здесь "сверху" и "слева" – расстояние левого верхнего угла заметки от верхнего и левого краев экрана соответственно. К этим существительным мы можем добавить следующие предполагаемые отношения:
связанное-ключевое-слово данные-заметки заметка-для-url
Теперь мы должны сконструировать факты на основе этих терминов.
Факты могут рассматриваться как триплеты субъект-предикат-объект или,
в терминологии
Третий вопрос поможет нам выявить "слабые" термины, чтобы ограничить число субъектов в нашей модели. Результаты анализа представлены в таблице 11.4 (цифры указывают на пункты обсуждения в последующем тексте).
| Термин | Сущность? | Отношение? | Свойство? |
|---|---|---|---|
| заметка | V | V 3. | |
| ключевое-слово | V | 1. | |
| URL | V | V 3. | |
| аннотация | 2. | V | |
| подробности | 2. | V | |
| сверху | 2. | V | |
| слева | 2. | V | |
| ширина | 2. | V | |
| высота | 2. | V | |
| связанное-ключевое-слово | V | V | |
| данные-заметки | V 4. | ||
| заметка-для-url | V | V |
На основе этого анализа мы можем сделать некоторые выводы, а ряд вопросов требует дополнительного обсуждения. Начнем с выводов: ключевое-слово представляет собой сущность; данные-заметки – отношение; аннотация, подробности, сверху, слева, ширина и высота – свойства для описания других сущностей. Мы можем быть уверены в этом, поскольку в каждой из соответствующих строк таблицы присутствует лишь одна отметка.
Теперь обсудим проблемы, возникшие при анализе терминов.
1. Мы полагаем, что конкретные ключевые слова не могут
рассматриваться как свойства другого термина, поскольку это означало
бы, что на основе этих ключевых слов должны быть образованы свойства
2. Эти термины не имеют собственных свойств, поэтому нет оснований считать их самостоятельными сущностями. Очевидно, они являются свойствами каких-то других сущностей, например URL или заметки.
3. Нам не вполне ясна ситуация с заметкой и URL. Является ли один из этих терминов свойством другого или же они независимы? Пока лучше считать, что оба термина – сущности.
4. Смысл такого термина, как "данные заметки" не вполне
ясен. Он не указывает ни на конкретные данные, ни на отношение между
ними, ни на какую-либо другую определенную информацию. Можно сравнить
этот неопределенный термин с "аннотацией", которая является
конкретным фрагментом данных, связанным с заметкой. Фактически мы
невольно привнесли в нашу модель
На основе нашего анализа мы можем сформулировать факты, перечисленные в листинге 11.15.
<- заметка, ?, URL -> <- URL, ?, заметка -> <- заметка, URL, ? -> <- URL, заметка, ? -> <- ключевое-слово, ?, ? -> <- заметка, аннотация, ? -> <- заметка, подробности, ? -> <- заметка, сверху, ? -> <- заметка, слева, ? -> <- заметка, ширина, ? -> <- заметка, высота, ? -> <- ?, связанное-ключевое-слово, ? -> <- ?, заметка-для-url, ? ->
Первые четыре факта представляют собой четыре варианта разрешения неопределенности, с которой мы столкнулись. Мы должны сделать выбор, исходя из потребностей приложения. Мы вернемся к этой проблеме после того, как разберем более простые вопросы.
Шесть следующих фактов с субъектом "заметка" тривиальны.
Каждый из них будет содержать в качестве объекта простое значение,
следовательно, этим объектом не может быть ). Мы будем использовать тип , который
представляет собой простую строку. Тогда эти факты примут следующий
вид:
<- заметка, аннотация, Literal ->
Факт с предикатом связанное-ключевое-слово связывает между собой два ключевых слова. Очевидно, что субъектом и объектом этого факта должны быть ключевые слова. Заменив для краткости предикат на "связано", получаем следующий факт:
<- ключевое-слово, связано, ключевое-слово ->
Использование ключевых слов в фактах создает проблему имен. Нам
известно, что ключевое слово должно быть представлено посредством : (мы используем английское слово
" будет присвоен следующий
urn:notetaker:keyword:foo
Нам также понадобится доступ к самой строке ключевого слова. В
последующих лекциях мы увидим, что извлечь подстроку из
<- urn:notetaker:keyword:{строка ключевого слова},
метка, "{строка ключевого слова}" ->
Наконец мы должны разобраться с вопросом о соотношении заметки и URL. Каждому URL соответствует одна заметка, и каждой заметке соответствует один URL. Необходимо решить, являются ли они отдельными сущностями. Если это так, нам понадобится каким-то образом описать связь между ними. Если их нельзя рассматривать как отдельные сущности, то одна из них, вероятно, будет свойством другой.
Если считать URL и заметку отдельными сущностями, каждая из них
должна иметь собственный
Таким образом, мы приходим к выводу, что заметке недостает собственной идентичности, и она должна каким-то образом зависеть от URL. Поскольку заметка не имеет идентичности (не может быть поименована), она не может быть субъектом или объектом никакого факта. Поскольку она не имеет "собственного значения", она не может быть представлена литералом. Таким образом, заметка как сущность, самостоятельная или зависимая, просто не существует. Мы исключаем ее из нашей модели, оставляя только URL, к которому относится эта заметка. Это решает большинство проблем, связанных с первыми четырьмя фактами листинга 11.15.
Такой результат может показаться странным, особенно для читателя,
который знаком с объектно-ориентированным или реляционным
моделированием. Разве заметка не является центральным объектом всего
приложения NoteTaker? Разве мы не вправе создавать в нашей модели
любые объекты или сущности, которые сочтем необходимыми? Ответ на
первый вопрос – "да", а на второй – "нет". Да,
заметка действительно является центром приложения, но, как выяснилось,
не его
Итог этого рассуждения прост – чтобы использовать сущность в модели
данных
В листинге 11.16 представлены факты после произведенных нами изменений:
<- URL, аннотация, Literal -> <- URL, подробности, Literal -> <- URL, сверху, Literal -> <- URL, слева, Literal -> <- URL, ширина, Literal -> <- URL, высота, Literal -> <- ключевое-слово, метка, Literal -> <- ключевое-слово, связано, ключевое-слово ->
Очевидно, что в этом списке отсутствует факт связи между ключевым
словом и заметкой (точнее, с URL, которому соответствует заметка). Мы
не затрагивали этой связи в процессе анализа, поскольку нам не было
ясно, являются ли ключевые слова сущностями или свойствами. Мы не
можем использовать конкретные ключевые слова в качестве свойств
(предикатов), поскольку каждое ключевое слово имеет свой
<- URL, ключевое-слово, urn-ключевого-слова -> <- urn-ключевого-слова, url-заметки, URL->
Каждому URL (и заметке) может соответствовать ноль или более фактов первого типа. Вместо этого (или в дополнение к этому), каждому ключевому слову может соответствовать ноль или более фактов второго типа.
В предлагаемом решении каждая заметка (каждый URL) может иметь
несколько свойств "ключевое слово". Можем ли мы использовать
для их хранения контейнер <Seq>? К сожалению, это
не так просто. Пойдя по такому пути, мы должны будем использовать
отдельный контейнер для каждого URL с определенной заметкой. Какое имя
должен иметь такой контейнер? Это должен быть <Seq>. Мы будем
использовать первый из предложенных вариантов:
<- URL, ключевое-слово, urn-ключевого-слова ->
Таким образом, мы завершили третий и четвертый этапы нашего плана –
выразили всю необходимую информацию о
<- http://saturn/test.html, аннотация, "Моя аннотация" -> <- http://saturn/test.html, подробности, "Мои подробности" -> <- http://saturn/test.html, сверху, "100" -> <- http://saturn/test.html, слева, "90" -> <- http://saturn/test.html, ширина, "80" -> <- http://saturn/test.html, высота, "70" -> <- http://saturn/test.html, ключевое-слово, urn:notetaker:keyword:test -> <- http://saturn/test.html, ключевое-слово, urn:notetaker:keyword:cool -> <- urn:notetaker:keyword:test, метка, "test" -> <- urn:notetaker:keyword:cool, метка, "cool" -> <- urn:notetaker:keyword:test, связано, urn:notetaker:keyword:cool ->
Последний факт выражает связь между ключевыми словами. Мы могли бы сформулировать и обратный факт, поменяв местами субъект и объект. Однако в этом случае мы получили бы множество избыточных фактов для заметки со множеством ключевых слов. Поэтому здесь мы ограничились минимумом фактов, необходимых для описания связи между ключевыми словами.
Пятый и шестой этапы нашего плана связаны с эффективностью доступа
к необходимым данным документов
Мы хотим, чтобы помимо выполнения этих видов поиска, приложение могло легко и быстро добавлять, удалять и изменять заметки. Эти задачи достаточно просты, поэтому мы сосредоточимся на приведенном списке, который фактически представляет собой набор запросов.
Mozilla может находить факты в документе
<Bag >, имеющий urn :notetaker:notes. При выполнении запросов 1, 2 и 3 этот контейнер может использоваться для облегчения поиска заметки и ее данных.<bag >, имеющий urn :notetaker:keywords . Запрос 4 сможет использовать этот контейнер для получения списка ключевых слов.Запрос 5 очень сложен, поскольку он требует просмотра большого количества фактов, имеющих отношение к ключевым словам. На данном этапе мы вряд ли можем предпринять что-либо для ускорения этого запроса. Как бы он ни выполнялся, для этого понадобится посмотреть все факты о связях между ключевыми словами или большую их часть.
Поскольку предполагается, что в документе < и другие
теги-контейнеры представляют собой субъекты фактов, мы добавим тег
верхнего уровня <Description>, имеющий .
Оба наших контейнера < будут значениями свойств этого
тега.
К этому и сводится все необходимое нам моделирование. Седьмой этап
плана представляет собой механическое преобразование
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmnls:NT="http://www.mozilla.org/notetaker-rdf#>
<Description about="urn:notetaker:root">
<NT:notes>
<Seq about="urn:notetaker:notes"/>
</NT:notes>
<NT:keywords>
<Seq about="urn:notetaker:keywords"/>
</NT:keywords>
</Description>
</RDF>
Если добавить к этому документу факты о заметке, представленные в
листинге 11.17, результатом
будет документ, представленный в листинге
11.19
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmnls:NT="http://www.mozilla.org/notetaker-rdf#>
<Description about="urn:notetaker:root">
<NT:notes>
<Seq about="urn:notetaker:notes">
<li resource="http://saturn/test.html"/>
</Seq>
</NT:notes>
<NT:keywords>
<Seq about="urn:notetaker:keywords">
<NT:keyword resource="urn:notetaker:keyword:cool/>
<NT:keyword resource="urn:notetaker:keyword:test/>
</Seq>
</NT:keywords>
</Description>
<!-- одна заметка -->
<Description about="http://saturn/test.html">
<NT:summary>Моя аннотация<NT:summary/>
<NT:details>Мои подробности<NT:details/>
<NT:top>100<NT:top/>
<NT:left>90<NT:left/>
<NT:width>80<NT:width/>
<NT:height>70<NT:height/>
<NT:keyword resource="urn:notetaker:keyword:test"/>
<NT:keyword resource="urn:notetaker:keyword:cool"/>
</Description>
<!-- строки ключевых слов -->
<Description about="urn:notetaker:keyword:test label="test"/>
<Description about="urn:notetaker:keyword:cool label="cool"/>
<!-- связи между ключевыми словами, пока есть одна -->
<Description about="urn:notetaker:keyword:test">
<NT:related resource="urn:notetaker:keyword:cool">
</Description>
</RDF>
Некоторые теги <NT: повторяются в этом файле. При
разработке всегда существует выбор между простотой данных и простотой
системы, которая должна делать запросы к этим данным. В данном случае
мы допустили некоторое
Таким образом, мы завершили работу над
Как правило, обработка данных
Документы
Если вы из какого-либо скрипта модифицируете источник данных
Автоматическое построение графа произвольного
Если вы не знаете точно, в каком состоянии находится ваше хранилище фактов (например, вы многократно модифицировали его из своей программы), существует легкий способ записать его текущее состояние на диск. Для этого используется код, приведенный в листинге 11.20.
// подготовка ..
var Cc = Components.classes;
var Ci = Components.interfaces;
var comp = Cc["@mozilla.org/rdf/rdf-service;1"]
var iface = Ci.nsIRDFService;
var svc = comp.getService(iface);
var ds = svc.GetDataSource("file:///C|/tmp/test.rdf");
var rds = ds.QueryInterface(Ci.nsIRDFRemoteDataSource);
// .. обычная работа с хранилищем фактов ..
function dumpRDF()
{
// чтобы произошла запись в файл, должно быть
сделано хотя бы одно изменение
var sub = svc.GetResource("urn:debug:subject");
var pred = svc.GetResource("DebugProp");
var obj = svc.GetResource("urn:debug:object");
ds.Assert(sub, pred, obj, true);
rds.Flush(); // записать в файл
}
Этот код создает источник данных dumpRDF() может быть вызвана в любой момент
после завершения загрузки источника (это можно проверить при помощи
флага или используя объект-наблюдатель). Функция dumpRDF()
всего лишь добавляет один факт к хранилищу фактов и записывает текущее
состояние хранилища в исходный файл. Иными словами, файл
синхронизируется с состоянием хранилища в памяти. Факт добавляется
для того, чтобы состояние хранилища гарантированно изменилось, и
произошла запись на диск. При просмотре файла этот факт будет
выглядеть примерно следующим образом:
<RDF:Description about="urn:debug:subject"> <DebugProp resource="urn:debug:object"/> </RDF:Description>
DebugProp и debug – простые строки, не имеющие специального
значения.
Системы обработки фактов отличаются от обычных систем обработки
данных. Для их понимания необходимо усвоить целый ряд новых терминов:
факт,
Внутри платформы Mozilla содержится ряд относительно тяжеловесных
структур и модулей, которые интенсивно обмениваются информацией в
процессе обработки и отображения содержимого. Каналы и источники
данных – разновидности таких структур, тесно связанные с
Внутри платформы
После всех сложностей
В этой лекции излагаются основы
Немногие приложения могут делать что-либо полезное, не получая
информации извне, и приложения Mozilla не составляют исключения.
Эта лекция посвящена, прежде всего, концепциям, лежащим в основе
Для того чтобы понять смысл многих компьютерных технологий, часто
достаточно беглого взгляда. Однако эта стратегия не работает при
встрече с действительно новыми и необычными подходами. В этом случае
приходится притормозить и заняться систематическим изучением
материала.
Итак, что же такое
Я ходил в магазин. Луна состоит из зеленого сыра. Том, Дик и Гарри – братья. Эта функция никогда не используется. Каждый человек должен найти собственный путь в жизни.
Неважно, являются ли эти утверждения истинными. Неважно, каков их
источник, и согласен ли с ними хоть кто-нибудь. Важно то, что их можно
записать некоторым универсальным способом (в данном случае – на
русском языке). Записывая факты, мы перемещаем их из своего сознания
туда, где их можно зафиксировать в соответствии с определенными
правилами или
Окружающий мир, включая сферу информационных технологий,
насыщен "фактоподобной" информацией. Однако подавляющее
большинство сведений не представлено в форме, удобной для обработки
фактов. Лишь немногие программисты в своей практике сталкиваются со
специализированными системами обработки фактов, однако код любого из
них содержит множество подразумеваемых фактов. Эти подразумеваемые
факты используются для решения других задач. Напротив,
Примером крайне примитивной и тривиальной системы хранения
"фактоподобной" информации, не использующей формата
<A HREF="http://www.mozilla.org/" ADD_DATE="961099870" LAST_VISIT="1055733093" ICON="http://www.mozilla.org/images/mozilla-16.png" LAST_CHARSET="ISO-8859-1"> The Mozilla Organization </A>
Этот фрагмент содержит ряд сведений об указанном URL: дату его
добавления к списку закладок, дату последнего посещения и т.д.
Атрибуты XML, в которых хранится эта информация, могут рассматриваться
как простые данные или как описание фактов. Хотя для описания фактов
можно использовать простой XML (или архаичный псевдо-HTML, как в этом
примере), лучше использовать специализированное приложение XML с
определенным синтаксисом. Как раз таким приложением является
Многие специалисты называют информацию такого рода метаданными.
Предполагается, что этот термин позволяет разграничить информацию (в
данном случае – содержимое web-документа, на который указывает URL) и
"информацию об информации" (описание документа и самого
URL), которая и называется метаданными. На практике, если программист
пишет код для работы с файлом закладок, единственной интересной для
него информацией являются так называемые метаданные – содержание этого
файла. С его точки зрения метаданные оказываются обычными данными, с
которыми он должен работать. То, что для одного человека является
метаданными, для другого – просто данные. Таким образом, при изучении
Говоря коротко, термин "метаданные" часто используется
без необходимости. С точки зрения программиста единственным элементом
<Description about="file:///local/writing/" open="true"/>
Говоря попросту, эта строка утверждает, что папка /local/writing/
открыта. Более строгая интерпретация в терминах open, значением (объектом) которого является
анонимная строка литералов "true"". Это довольно
неуклюжий язык, и сейчас нам предстоит разобраться, что все это
означает.
Наконец, следует сказать, что
На схеме в начале этой лекции показано, что поддержка
К сожалению, производительность работы с
Классический пакет приложений Mozilla в значительной степени
основан на
Классический браузер и Netscape 7 создают и используют
Изучение
Синтаксис XML отличается высокой избыточностью. Когда наши глаза и
мозг поглощены разбором формального синтаксиса, без надлежащего опыта
бывает трудно сосредоточиться на содержательных вопросах. Даже
разработчики официальной спецификации
Популярные введения в
Кроме того,
Наконец,
Тем не менее,
В основе синтаксиса любых приложений XML лежит концепция элемента,
который часто соответствует одному тегу. В основе
Программист может получить первое представление о мире фактов по
аналогии с известными технологиями, которые до некоторой степени
"фактоподобны". В качестве примеров можно привести язык SQL
и утилиту make. Управление записями в базе данных при помощи таких
INSERT, DELETE и особенно SELECT до некоторой
степени сходно с управлением фактами. Запрос к базе данных аналогичен
запросу к системе обработки фактов. С другой стороны, правило
командного файла утилиты make(1), на основе которого утилита
определяет, какие файлы нуждаются в новой компиляции, также
"фактоподобно". Правило из командного файла можно
рассматривать как факт о файлах и "целях" ( target ) утилиты make. Еще один пример "фактоподобного" командного файла –
конфигурационный файл программы sendmail, весьма сложный для
чтения.
У всех этих систем есть общее свойство: хранимые элементы данных
независимы друг от друга и содержат несколько значений – каждый факт
состоит из нескольких частей (полей в случае записи в базе данных,
цели и зависимостей - в случае файла make ). Работа с фактами
подразумевает использование специального приложения, будь то сервер
баз данных, утилита make или агент пересылки почты. Это приложение
обрабатывает факты, после чего передает результаты пользователю или
другой программе
Факты используются для описания и моделирования данных.
Программисты, как правило, используют для моделирования структуры
данных. Те программисты, которым приходится заниматься
проектированием, могут использовать для этого словари данных и
диаграммы
Пожалуй, простейший способ понять, чем факты отличаются от
традиционных данных, – записать то и другое. Предположим, что мальчик
и его собака играют с мячом на пляже. Описание этой ситуации,
включающее четыре объекта реального мира (мальчик, пляж, собака, мяч),
может храниться как структура данных или как факт. Начнем с обычных
структур данных. В JavaScript эти данные можно сохранить в форме
{boy:"Том", dog:"Спот", ball:"теннис", beach:"Уайкики"}
Эта запись довольно близка и к структурам данных в C/C++ ( struct ).
Ту же информацию можно сохранить и в виде массива JavaScript:
[ "Том", "Спот", "теннис", "Уайкики" ]
Все наши данные имеют один и тот же тип – строка, что соответствует идее массива. Массив с этими данными можно было бы создать и в C/C++. В программе на Perl можно было бы использовать список:
( "Том", "Спот", "теннис", "Уайкики", )
Существует много способов сохранить одни и те же данные, и каждый из них имеет свои достоинства и недостатки. Использование объекта или класса подразумевает, что все элементы данных (поля объекта) имеют общего владельца (объект), и во многих языках каждый из них имеет определенный тип. Использование массива подразумевает, что элементы пронумерованы и имеют один и тот же тип. Использование списка означает, что элементы упорядочены. Программист может выбрать наиболее подходящий вариант для конкретной задачи.
Информация может быть записана и в виде факта – с использованием кортежа.
< Том, Спот, теннис, Уайкики >
Однако в этом варианте и других, подобных ему,
<- Том, Спот, теннис, Уайкики ->
Каждый из элементов
Использование угловых скобок < и > намекает на существенную
разницу между
Обработка декларации-
Пример
В принципе,
Предположим, что нам необходимо зафиксировать эту ситуацию более
подробно. Типичный подход к моделированию – начать с выявления
существительных. На их основе могут быть спроектированы объекты,
var boy = { Pid:1, name:"Том", Did:null, Bid:null };
// name - имя
var dog = { Did:2, name:"Спот", Pid:null, Bid:null };
var ball = { Bid:5, type:"теннис", color:"зеленый" };
// type - тип, color - цвет
boy.Did = dog; // связать объекты друг с другом
boy.Bid = ball;
dog.Pid = boy;
dog.Bid = ball;
Аналогичное моделирование может быть выполнено при помощи
<- 1, Том, 2, 5 -> <- 2, Спот, 1, 5 -> <- 5, теннис, зеленый ->
Как и в случае реляционных данных, связи между объектами
представлены парами одинаковых значений в разных
Обе попытки моделирования позволили описать некоторые существенные
факты, но одновременно выявили ограниченность обоих подходов. Исходное
описание ситуации таково: "Том и его собака
| Модель с объектами | Модель с |
|---|---|
| Объект для Тома | |
| Объект для |
|
| Объект для зеленого теннисного мяча | |
| Том связан со |
Том, 1, 2 и 5 связаны между собой |
| Том связан с зеленым теннисным мячом | Зеленый теннисный мяч и 5 связаны между собой |
| (Можно вывести дополнительную информацию) | (Можно вывести дополнительную информацию) |
Таблица 11.1 несколько приукрашивает ситуацию, поскольку учитывает
подразумеваемое знание о назначении каждого объекта и
Традиционное решение этой проблемы – создать дополнительные
таблицы, объекты и т.п. Решение, подходящее для мира фактов, – сделать
каждое существующее отношение
Предикатами называется особая группа
<- 1, Том, хозяин, 2, играет-с, 5 -> <- 2, Спот, принадлежит, 1, играет-с, 5 -> <- 5, теннис, зеленый ->
В этом примере отношения имеют тот же статус, что и другие данные.
Первый
Теперь добавим к нашему жаргону еще одно слово.
Описание ситуации в листинге 11.3 все же не идеально, поскольку
некоторые
<- 1, Том, хозяин, 2 -> <- 1, Том, играет-с, 5 -> <- 2, Спот, принадлежит, 1 -> <- 2, Спот, играет-с, 5 -> <- 5, теннис, зеленый ->
Ценой некоторого дублирования информации мы смогли разделить
предикаты, и теперь наши
<- 1, имя, Том -> <- 1, хозяин, 2 -> <- 1, играет-с, 5 -> <- 2, имя, Спот -> <- 2, принадлежит 1 -> <- 2, играет-с, 5 -> <- 5, тип, теннис -> <- 5, цвет, зеленый ->
Теперь мы имеем дело только с триплетами. Триплеты с одним
предикатом лежат в основе практически всех систем работы с фактами.
Думая об обработке фактов, следует опираться на концепцию триплетов с
одним предикатом, а не произвольных
Стоит отметить, что на пути выделения предикатов и отношений можно зайти слишком далеко. Последние два триплета в листинге 11.5 отличаются от остальных. Теннис и зеленый представляют собой простые описательные свойства, а не элементы ситуации, такие как мальчик или мяч. Подобно тому, как можно создать чрезмерно нормализованную базу данных со многими таблицами или множество тривиальных классов в случае объектного проектирования, можно сформулировать и избыточное количество тривиальных фактов. Однако все зависит от задачи – если тривиальные факты представляют интерес в ее контексте, можно смело фиксировать их.
Поскольку триплеты широко используются, их элементы имеют
специальные названия. Как уже было сказано,
Факты об отношениях могут быть записаны различными способами.
Например, в языке
предикат(субъект, объект) plays-with(1,5) играет-с(1,5)
В языках
(предикат субъект объект) (plays-with 1 5) (играет-с 1 5)
Можно записывать такие факты и на естественном языке
субъект предикат объект 1 играет с 5
И, разумеется, факты об отношениях можно выразить на языке XML, для
чего и был разработан формат
<Description about="субъект" предикат="объект"/> <Description about="1" играет-с="5"/>
Наконец, для удобной и компактной записи фактов может
использоваться нотация для
<- субъект, предикат, объект -> субъект предикат объект
Если вы склонны придерживаться синтаксиса реального языка
программирования, можете следовать простой и ясной нотации
Рис. 11.1 Граф связей между кортежами 1 играет-с 5 5 тип теннис 1 имя Том 1 хозяин 2 2 принадлежит 1 2 имя Спот 5 цвет зеленый 2 играет-с 5
К настоящему моменту мы выработали подходящую структуру для описания факта. Какими же способами можно хранить ее в компьютере? Существует несколько вариантов.
Первый способ – хранить факты как набор независимых элементов. В
реляционной СУБД этому соответствуют отдельные записи в таблице с
тремя полями; в объектной технологии – коллекция элементов (например, set или ). Запись в
листинге 11.5 соответствует такому подходу.
Этот простой подход очень гибок. В любой момент можно добавить новые факты или удалить существующие. Не нужно поддерживать никакой внутренней структуры. Такое решение можно сравнить с обычным ведром – при необходимости вы просто "наливаете" в него факты или "выливаете" их.
Одно из главных преимуществ "ведра с фактами" – легкость объединения фактов из разных источников. Вы просто "наливаете" их в ведро, получая в результате одну большую коллекцию фактов. Когда вы обращаетесь к ней, все факты имеют одинаковый статус независимо от происхождения. Это просто объединение двух множеств.
Второй подход к хранению фактов основан на признании того, что
между отдельными фактами существуют связи, образующие некую структуру.
Она может храниться как традиционная структура данных, в которой связи
между
(рис 11.1) Связи между фактами, приведенными в листинге 11.5.Пожалуй, это слишком сложная схема для простой системы, состоящей
из мальчика, собаки и мяча. Более того, на ней недостает некоторых
линий – нам следовало бы добавить еще три связи между фактами,
содержащими "1" и три связи между фактами, содержащими
"2", доведя их общее число до 18. Чтобы сделать схему менее
громоздкой, добавим к ней вершины, вынеся идентификаторы из
(рис 11.2) Упрощенный граф связей между кортежами.Наш подход – выделение элементов из
(рис 11.3) Значительно упрощенный граф связей между кортежами.Наконец, мы можем заметить, что каждый предикат имеет ровно одну входящую и одну исходящую стрелки. Поэтому мы можем превратить предикаты в именованные стрелки (ребра), освободив граф от избыточных узлов (вершин). Результат этой процедуры показан на рисунке 11.4, на котором также изменено расположение некоторых элементов.
(рис 11.4) Граф связей между кортежами в нотации RDF.На этом рисунке ясно видны отношения, выражаемые предикатами, и их характер. Существуют второстепенные предикаты, которые служат лишь для описания идентификаторов (имя, цвет, тип), и более важные предикаты (хозяин, играет-с), содержащие информацию об отношениях между интересующими нас идентификаторами. Таким образом, решения использовать идентификаторы для каждого моделируемого объекта реального мира (см. листинги 11.1 и 11.2) и выделить идентификаторы на схеме (см. рисунок 11.2) оказались продуктивными. Как мы видим, идентификаторы играют важнейшую роль в построении компактной и выразительной схемы.
Граф на рисунке 11.4 соответствует официальной нотации
Данные
Наконец, существует третий способ организации фактов, часто
используемый в
Контейнер представлен на схеме

(рис 11.6) Граф RDF, на котором сходные термы объединены при помощи линии.(рис 11.5) Граф RDF, на котором сходные термы объединены при помощи контейнера.Контейнеры представляют собой простой механизм структурирования
данных. Они также поддерживают запросы к коллекциям фактов.
Разработчик приложения может использовать контейнер в качестве
частичного индекса,
Итак, факты могут храниться в виде простого набора триплетов или
сложного графа, организованного вокруг идентификаторов. Между этими
полюсами находится частичная структура, задаваемая контейнером,
которую можно сравнить с маршрутом, нарисованным на карте. Набор
фактов называется хранилищем фактов. Сложные хранилища фактов
называются
Факты могут описывать другие факты. В некоторых особых ситуациях это следует иметь в виду, но в большинстве случаев полезнее игнорировать такую возможность. Некоторые базовые сведения о фактах, описывающих факты, приведены в этом разделе. Факты, зафиксированные в примере с мальчиком и собакой, неявно подразумевают множество других фактов, которые могут быть выражены в явном виде. Некоторые из них следуют из устройства нашей маленькой коллекции фактов, другие истинны почти автоматически. Все следующие примеры основаны на единственном факте:
<- 1, имя, Том ->
Одна из групп дополнительных фактов, следующих из устройства коллекции, – информация о типах. Программист, разрабатывающий коллекцию фактов, может решить хранить в ней типизированные данные. Например, следствием единственного факта, указанного выше, могут быть следующие факты:
<- 1, тип, integer -> <- Том, тип, string ->
Эти факты указывают типы для субъекта и объекта ранее приведенного
факта. Они содержат дополнительную информацию о другом факте и
являются аналогом словаря данных или
Здесь уместно повторить сказанное в начале этой лекции. Многие
специалисты называют информацию такого рода метаданными.
Предполагается, что этот термин позволяет разграничить информацию (в
данном случае – содержание web-документа, на который указывает URL) и
"информацию об информации" (описание документа и самого
URL), которая и называется метаданными. На практике, если программист
пишет код для работы с файлом закладок, единственной интересной для
него информацией являются так называемые метаданные – содержание этого
файла. С его точки зрения метаданные оказываются данными, с которыми
он должен работать. То, что для одного человека является метаданными,
для другого – просто данные. Таким образом, при изучении
Говоря коротко, термин "метаданные" часто используется
без необходимости. С точки зрения программиста единственным элементом
Следующие три факта являются истинными автоматически:
<- пример-факта, субъект, 1 -> <- пример-факта, предикат, имя -> <- пример-факта, объект, Том ->
Здесь пример-факта означает факт, приведенный в начале этого
раздела. Первый из трех фактов (с предикатом субъект) утверждает, что
субъектом исходного факта является 1. Согласно второму факту,
предикатом исходного факта является имя. Иными словами, все это факты
об исходном факте. Процесс построения таких фактов называется
Реификация сходна с извлечением метаданных, однако потенциально
ведет к гораздо более запутанным следствиям. Рассмотрим, например,
следующую проблему. Как было сказано выше, все существующие
(зафиксированные) факты считаются истинными, а все прочие – ложными.
Можем ли мы утверждать, что исходный факт (пример-факта) имеет
субъект, если не сформулирован первый из фактов
Еще одна группа фактов, которые можно сформулировать на основе существующих фактов, связана с именами. Разработчик, формирующий группу фактов, может пожелать дать имена элементам этих фактов. Используя все тот же пример, можно присвоить имена субъекту или объекту, подобно тому, как даются имена полям записи в базе данных, или король жалует дворянские титулы своим подданным:
<- 1, имя, идентификатор-лица-> <- Том, имя, имя-лица-> <- пример-факта, имя, определение-лица->
Эта процедура тоже создает возможности для путаницы. Исходный факт утверждает, что существует лицо по имени Том. Однако согласно первому из приведенных здесь фактов, строка "Том" имеет имя (тип) имя-лица, а исходный факт в целом – "существует лицо по имени Том" – имеет имя определение-лица. Итак, имя Тома – "Том", но оно, в свою очередь имеет имя имя-лица. Все эти тонкости не имеют практического значения для большинства разработчиков.
Наконец, следует отметить, что большинство аспектов многих подходов к моделированию данных могут быть выражены при помощи фактов с предикатами. Например, при помощи следующих предикатов можно формулировать факты, описывающие объектно-ориентированную модель:
является-подклассом имеет использует является-экземпляром
А этот набор предикатов может использоваться для описания реляционной модели:
имеет-ключ имеет-внешний-ключ один-ко-многим один-к-одному имеет-необязательный
С помощью подобных предикатов можно надстраивать сложные слои
семантики (например, объектную модель) над базовой системой простых
фактов. Однако это сложный процесс, с которым вряд ли справится
начинающий разработчик. Некоторые возможности такого рода
предусмотрены в самом языке
Наконец, новые факты могут быть выведены из существующих. В примере с мальчиком и собакой следующий факт может рассматриваться как следствие сформулированных фактов:
<- Том, играет-с, Спот->
Следует ли рассматривать его как следствие, зависит от правил
вывода и других допущений, принятых в конкретной системе. В конце
концов, если мальчик и собака играют с одним и тем же мячом, они,
вероятно, играют друг с другом. Вывод таких фактов является функцией
дедуктивных систем. Mozilla не выполняет
Факты, собранные вместе для обработки, содержатся в хранилище фактов. Последнее является аналогом базы данных применительно к фактам и, как правило, находится в оперативной памяти, а не на диске.
Подводя итоги этого введения, отметим, что триплеты с предикатом
представляют собой полезное подмножество простых
Хранилище фактов не имеет практического смысла, если нет возможности извлекать из него факты. Разработчику необходим способ получать нужные факты, игнорируя остальные.
По документам getElementById(),
или более сложных технологий, таких как XML Query или
Вместо этого документы grep(1).
Системы запросов не рассматриваются подробно в этой лекции, однако они основаны на концепции определенного факта. Определенный факт (иногда называемый конкретным фактом), представляет собой полностью известный факт. Все факты, обсуждавшиеся в этой лекции до настоящего момента, были определенными фактами.
В качестве примера рассмотрим следующее высказывание: "Том –
хозяин
<- Том, хозяин, Спот ->
Мы можем сформулировать и другое высказывание: "Том владеет собакой". Эквивалентный факт можно записать как:
<- Том, хозяин, собака ->
Однако если принять во внимание, что в мире существует множество собак, нужно сделать вывод, что данное высказывание не позволяет ответить на вопрос "Какой собакой владеет Том?" В этом случае высказывание "Том владеет собакой" является неопределенным, поскольку оно не позволяет однозначно установить объект (конкретную собаку). Адвокат мог бы сказать: "Это утверждение необоснованно, поскольку вы не можете указать конкретную собаку, которой владеет Том". Таким способом он подчеркнул бы, что ваше высказывание слишком туманно, чтобы быть истинным. Лучший факт, который мы можем записать в такой ситуации, имеет следующий вид:
<- Том, хозяин, ??? ->
Знаки вопроса не являются какой-либо специальной синтаксической конструкцией, они лишь указывают на неопределенный объект. Вы вряд ли сможете сделать что-либо с таким неопределенным фактом, представляющим собой противоположность определенному.
Однако если компьютер, в отличие от вас, знает, какая собака принадлежит Тому, вы можете передать неполный факт компьютеру в качестве запроса. Компьютер, исполняя соответствующую программу, может сопоставить неполный факт (называемый целью) со всеми зафиксированными фактами и возвратить лишь те факты, которые согласуются с ним. Этот процесс называется унификацией, в реализации Mozilla он представляет собой простое сопоставление с образцом. Таким образом вы найдете всех собак, принадлежащих Тому, или всех животных, принадлежащих Тому, или вообще все, что принадлежит Тому. То, что вы получите в ответ, зависит от того, какие факты содержатся в хранилище фактов. В любом случае, системы запросов и фильтрации Mozilla выполнят необходимые действия.
Разработчик осуществляет поиск или фильтрацию определенных фактов
Подводя итоги, отметим, что факты могут храниться подобно данным и извлекаться при помощи системы сопоставления цели с определенными данными.
Синтаксис
Разумеется, наиболее важными из них являются стандарты
(спецификации), относящиеся собственно к
На первом этапе стандартизации
http://www.w3.org/TR/1999/REC-rdf-syntax-19990222.
"Окончательная рекомендация по модели и синтаксису
http://www.w3.org/TR/2000/CR-rdf-schema-20000327. Этот документ
разрабатывался в течение нескольких лет. Он определяет схему
Второй этап стандартизации
http://www.w3.org/TR/rdf-syntax-grammar/, "Спецификация
синтаксиса
http://www.w3.org/TR/rdf-schema/, "Язык описания словаря
Существует также ряд пояснительных документов, посвященных
различным аспектам
Из перечисленных спецификаций Mozilla практически полностью реализует первый документ (рекомендацию 1999 г.) и некоторые новые возможности, введенные третьим документом (пересмотренной рекомендацией).
Другие стандарты, тесно связанные с
Эти стандарты предлагают способ описания фактов при помощи тегов XML. Субъекты и объекты фактов могут быть представлены атрибутами тегов или (в случае объектов) текстовыми узлами, заключенными в теги. Однако стандарты определяют лишь небольшое количество конкретных тегов. Предполагается, что дополнительные теги и атрибуты определяются разработчиком конкретного приложения.
Эти дополнительные имена образуют словарь, который может быть
формально описан в документе
Mozilla не использует
Документ
http://www.w3.org/1999/02/22-rdf-syntax-ns#
Файлы с документами
text/rdf text/xml
Однако версия 1.4 еще не поддерживает официального типа
application/rdf+xml
Основная цель
<факт субъект="..." предикат="..." объект="..."/> <факт> <субъект .../> <предикат .../> <объект .../> </факт> < субъект ... предикат="..." объект="..."/>
Однако в
<факт субъект="..."> <предикат>объект</предикат> </факт>
Эта запись отражает лишь общую концепцию синтаксиса
<Description about="http://www.mozilla.org/"> <NC:LastVisited>10 января 2004</NC:LastVisited> </Description>
Такой синтаксис допускает вложение одних фактов в другие. Он может
служить основой для нескольких видов сокращенной записи и сходен с
некоторыми web-технологиями. К сожалению, терминология
При разработке
| Термин, относящийся к фактам | Термин |
Термины web-технологий, повлиявшие на терминологию |
Синтаксис |
|---|---|---|---|
| Факт | Описание | Описание документа или запись | <Description>, <Seq>, <Alt>, < |
| Субъект | Ресурс | URL | about=, id= |
| Предикат | Свойство (и ресурс) | Свойство объекта, свойство CSS, атрибут XML | Определяется пользователем |
| Объект | Значение (или ресурс) | Значение свойства, значение атрибута | resource=, простой текст |
На практике полезно комбинировать оба подхода. С общей точки
зрения,
В качестве примера рассмотрим уже встречавшийся нам простой тег <Description> определяет субъект факта (на который
указывает атрибут about этого тега). Если тег имеет содержимое, оно
представляет прочие <NC:LastVisited> представляет
собой предикат, а его содержимое, простая строка "10 января
2004", – объект. В терминологии <Description> определяет ресурс.
Этот ресурс может иметь свойства, выраженные другими тегами. Тег <NC:LastVisited> – одно из таких свойств, значением которого
является "10 января 2004".
Терминология
Вот полный список основных тегов
<RDF> <Description> <Seq> <Bag> <Alt> <li>
Последние четыре тега являются избыточными – эквивалентные им
конструкции могут быть выражены при помощи тега <Description> –
так что
<Statement> <subject> <predicate> <object>
Эти теги предназначены для <Statement>
используется для
<, <Seq> или <Alt>, а также тегов <li>, в которые заключаются элементы
контейнера. Контейнер вместе со своим содержимым образует коллекцию.
Эта коллекция может быть помещена вместо объекта какого-либо факта.
Контейнер выглядит следующим образом:
<Description>
<Bag>
<li>объект 1</li>
<li>объект 2</li>
<li>объект 3</li>
</Bag>
</Description>
В обычном факте между объектом и субъектом (или между ресурсом и
значением свойства) существует отношение "один к одному". У
каждого объекта есть один субъект. В случае контейнеров отношение
между фактом и объектом имеет вид "один ко многим", причем
минимально возможное число объектов у субъекта равно нулю. Контейнеры
Одно из возможных применений контейнера – поддержка списка
свободных мест в системе заказа билетов. Каждое место является
ресурсом; в системе должно быть отражено состояние всех мест – как
свободных, так и зарезервированных. Список свободных мест может быть
организован отдельно от фактов о состоянии конкретных мест при помощи
контейнера. Соответствующий фрагмент
<Description>
<Description id="место:A1">
<крайнее>true</крайнее>
</Description>
<Description id="место:A2">
<зарезервировано>Тим</зарезервировано>
<крайнее>false</крайнее>
</Description>
<Description id=" место:A3">
<крайнее>false</крайнее>
</Description>
<Description id=" место:свободные">
<Bag>
<li resource="место:A1"/>
<li resource="место:A3"/>
</Bag>
</Description>
В этом фрагменте для каждого места указано, является ли оно крайним
(у прохода) и в том случае, если место не свободно, имя того, кто его
зарезервировал. Синтаксис место: относится к воображаемой < содержит ссылки на два свободных
места. Синтаксис тегов <li> в этом примере – один из способов
сокращения, допустимых языком
Таким образом, контейнеры могут использоваться для того, чтобы
предоставить программисту доступ к подмножествам фактов. Элементы
контейнера указывают на субъекты подмножества какого-либо множества
фактов, описанных за пределами контейнера. Просматривая контейнер,
можно получить доступ к этим фактам. Контейнеры могут рассматриваться
как простая структура данных для фактов и как простой механизм
навигации. В системе заказа билетов программист может зарезервировать
место, выбрав его из контейнера со свободными местами, добавив
вложенный тег (предикат) <зарезервировано> к соответствующему
тегу <Description>, а затем удалив место из контейнера.
В объектно-ориентированной терминологии контейнер "использует" объекты – члены коллекции. Контейнер содержит лишь ссылки на них, а не сами объекты.
Теги-контейнеры и соответствующие коллекции всегда могут быть заменены эквивалентной конструкцией из простых фактов. Об этом рассказано в описании отдельных тегов.
В примере с мальчиком и собакой мы стремились снабдить каждый
элемент, моделируемый при помощи фактов, идентификатором. В отличие от
многих других приложений XML, в
Первый способ использования идентификаторов – обозначение целого
факта. Для этого к тегу, выражающему данный факт, добавляется атрибут id. URL документа id
какого-либо факта из данного документа, является уникальным
идентификатором факта в глобальном масштабе. Согласно документу <A> без
атрибута HREF, на которые ссылается часть URL после символа #,
маркируют лишь определенное место в едином документе-ресурсе. Вот
пример идентификатора
<Description ID="printEnabled" ... />
Возможно, этот файл содержит информацию о состоянии подсистемы
печати, и атрибут ID позволяет обратиться к конкретному факту,
используя осмысленное имя.
Второй способ использования идентификаторов в
Однако такая непосредственность не обязательно должна иметь место.
Так, на том же листинге записано несколько фактов о Томе. При этом сам
Том – реальный мальчик – не присутствует в этих фактах
непосредственно. Вместо этого мы используем число (1), имея в виду,
что в данной группе фактов оно представляет Тома. :)
или URL web-документа, содержащего запись о Томе. Любой факт,
субъектом которого является строка, совпадающая с этим URL, является
фактом о Томе. В терминологии web-разработчика Том является ресурсом,
на который указывает URL.
Однако
Примечательно, что id, значением которого должен быть
корректный URL. Для удобства чтения URL предиката как правило содержит
слово, поясняющее его общий смысл, например http://www.example.com/#Owner
(владелец).
Таким образом, при необходимости факты можно выражать при помощи
одних лишь идентификаторов-URL. Фактически такие идентификаторы
являются указателями на
Здесь, однако, существует одна сложность. Любой URL в документе
Строго говоря, идентификаторы, заменяющие
<Description> или
контейнер не имеют идентификатора. Это факты с неопределенным
субъектом или анонимные факты. Документ <Description> без
идентификаторов.
Тег < является
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
Для этого тега не определено никаких специальных атрибутов. В нем
могут встречаться лишь декларации пространств имен XML, добавляющие
словари (дополнительные наборы тегов) для использования в документе.
Эти декларации играют ту же роль, что и указание
| URL пространства имен | Префикс xmlns | Где определено | Использование |
|---|---|---|---|
| http://www.w3.org/1999/02/22-rdf-syntax-ns# | |
http://www.w3.org | Базовая поддержка |
| http://home.netscape.com/WEB-rdf# | Web |
Код Mozilla | Закладки и метки времени |
| http://www.mozilla.org/rdf/chrome# | |
Код Mozilla | Управление пакетами |
| http://home.netscape.com/NC-rdf# | nc |
Код Mozilla | Общего назначения |
| http://www.mozilla.org/LDAPATTR-rdf# | ldapattr |
JavaScript, на основе свойств |
Поддержка |
| http://www.mozilla.org/inspector# | |
JavaScript | Инспектор DOM |
За исключением первой строки таблицы, ни одному из указанных URL не
соответствует реальный документ. URL, содержащие "netscape",
являются наследием Netscape Communicator 4.x. Префиксы представляют
собой рекомендации, основанные на существующих соглашениях. Из
перечисленных префиксов в различных компонентах Mozilla наиболее
широко используются web, и nc. Чтобы использовать пространство
имен, нужно знать ключевые слова (теги), предоставляемые этим
пространством. Эти ключевые слова обсуждаются ниже в разделе
"Теги предикатов". Разработчик приложений может добавлять к
Содержимым тега < являются теги-потомки. Его
непосредственными потомками могут быть тег <Description> и теги-
контейнеры <Seq> <.
Тег <Description> является основой всего языка <Description>. В
листинге 11.8 представлены два факта, выраженные с помощью одного тега <Description>.
<факт субъект="..."> <свойство1 ...>объект1</свойство1> <свойство2 ...>объект2</свойство2> </факт>
Этот фрагмент записан на псевдокоде, а не на синтаксически
корректном
В < из этого примера играет тег <Description>, который по сути является контейнером. Он, однако,
отличается от прочих контейнеров
Тег <Description> имеет следующие специальные атрибуты.
ID about type
Каждый тег <Description> должен иметь атрибут ID или атрибут about. Если тег не имеет ни одного из этих атрибутов, считается, что
соответствующий факт имеет анонимный субъект. Этот субъект для
внешнего мира невидим (для него невозможно определить уникальный URL),
а в рамках данного документа он считается неопределенным
Считается, что атрибут ID имеет имя, которое совпадает с его
значением. Это имя можно добавить к URL документа ID тега <Description> имеет смысл в том случае, если у этого
тега есть ровно одно свойство. Субъект факта, определенного с
использованием атрибута ID, доступен для внешнего мира (как и в
предыдущем абзаце, речь идет не о физической доступности документа, а
о возможности адресации факта и его субъекта).
Атрибут about определяет субъект факта. Его значением должен быть
полный URL. Если атрибут about используется вместо атрибута ID, факт
как целое не имеет собственного URL и недоступен из внешнего мира.
Атрибут type указывает тип объекта факта (в терминологии type в документах type ;
атрибут type может рассматриваться как сокращенная запись этого
предиката.
Mozilla не поддерживает следующие специальные атрибуты тега <Description>:
aboutEach aboutEachItem bagID
Два первых атрибута не рекомендованы к применению последними
версиями спецификации bagID используется для
Тег <Description> и его содержимое могут быть записаны как
единственный тег <Description> без всякого содержимого. Это
можно сделать, записав предикат и объект как атрибут XML тега <Description> и значение этого атрибута соответственно.
Следующий фрагмент
<Description about="www.test.com/#Том"> <ns:Владелец>Спот</ns:Владелец > </Description>
В данном случае субъект и предикат представлены с помощью URL; объект представлен с помощью литерала. Предикат принадлежит пространству имен XML с префиксом ns. Это пространство было декларировано в начале документа, поэтому полный URL предиката нельзя установить на основании одного лишь данного фрагмента. Сокращенная запись того же фрагмента выглядит следующим образом:
<Description about="www.test.com/#Том" ns:Владелец="Спот"/>
Обратите внимание на префикс пространства имен перед атрибутом. Эта
возможность предусмотрена спецификацией XML, но не слишком часто
используется на практике. Сокращенная запись допустима лишь в том
случае, когда объект/значение является литералом, а не
Предикаты или свойства определяются разработчиком конкретного
приложения. Лучше всего найти уже разработанный набор тегов,
подходящий для конкретной цели. Разумеется, можно придумывать и
собственные теги в процессе разработки. Однако использование корректно
определенного пространства имен является признаком культуры
разработчика и того, что он продумал назначение своих данных,
представляемых в формате
превращает
любой тег в элемент-наблюдатель. Доступны следующие специальные
атрибуты:
ID parseType
Атрибут ID имеет то же назначение, что и в теге <Description>. Если родительский тег <Description>
содержит более чем один тег-предикат (т.е. представляет несколько
фактов), атрибут ID может быть добавлен к тегам-предикатам, чтобы
однозначно идентифицировать отдельные факты.
Атрибут parseType является указанием для синтаксического
анализатора type, обсуждаемого в
следующем разделе, и указывает, каким образом должна
интерпретироваться текстовая строка, представляющая значение/объект.
Атрибут parseType может принимать следующие значения:
Literal Resource Integer Date
Два первых значения предусмотрены спецификацией –
значение атрибута по умолчанию, оно подразумевает, что значение
является произвольной строкой. Resource означает, что строка значения
представляет Integer и Date являются дополнениями
Mozilla и указывают, что строка должна интерпретироваться как 32-битное
целое со знаком и как дата соответственно. Предполагается, что
дата может быть в любом из нескольких форматов, однако не все из них
поддержаны полностью. Самый надежный вариант – использовать формат
date(1), но в полученной строке заменить
"Date не должно содержать символов Unicode, выходящих за
пределы набора ASCII.
В type, соответствующий атрибуту type тега <Description>. Использование этого атрибута является сокращенным
вариантом следующей записи:
<rdf:type>value</rdf:type>
В данном случае является префиксом пространства имен
Пространства имен, перечисленные в таблице 11.3, также обеспечивают дополнительные наборы предикатов. Поскольку предикаты, по сути, являются элементами данных, сами по себе эти имена ничего не "делают".
В лекции 9 "Команды" было сказано, что платформа Mozilla
определяет множество команд, но все они связаны с тем или иным
приложением – Навигатором, Компоновщиком или
Полного списка этих предикатов не существует ни в документации, ни
даже в исходном коде. Чтобы ввести новый предикат, разработчику
достаточно добавить его в файл
Вновь создаваемое приложение на платформе Mozilla должно иметь
формально описанную
Существующим схемам данных нужно строго следовать лишь в том
случае, когда приложение должно создавать или изменять файлы
Теги-предикаты могут иметь атрибут resource. Он аналогичен атрибуту
about тега <Description>, но указывает на объект факта (значение
свойства). При использовании атрибута resource тег-предикат может не
иметь содержимого XML, а значением атрибута resource должен быть не
литерал, а корректный
<ns:Владелец parseType="Resource">www.test.com/#Spot</ns:Владелец>
Тогда ее сокращенная форма имеет следующий вид:
<ns:Владелец rdf:resource="www.test.com/#Spot"/>
Это применение атрибута resource не представляет трудностей для
понимания. Однако данный атрибут имеет и более сложное применение.
В простом случае, рассмотренном только что, значение атрибута resource участвует лишь в одном факте, на объект которого оно
указывает. Однако этот же объект может быть субъектом другого факта. В
данном случае применимо следующее весьма запутанное правило: если в
теге-предикате встречается атрибут resource, а также другие пары
атрибут-значение, эти пары интерпретируются так же, как если бы они
принадлежали тегу <Description>, субъектом которого (значением
атрибута about ) был бы resource
тега-предиката. Иными словами, внутри тега-предиката одного факта
могут быть определены другие, вложенные факты, причем объект
объемлющего факта является субъектом вложенных фактов.
Все это весьма сложно и запутанно, и не стоит тратить усилий на
изучение всех тонкостей, если только вы не разрабатываете сложное и
амбициозное приложение. Этот вариант сокращенной записи был предложен
для того, чтобы уменьшить количество вложенных тегов в документе
<Seq>, < и <Alt> – три тега-контейнера
<Seq> представляет собой
< представляет собой простую коллекцию элементов без
каких-либо ограничений на ее состав.
<Alt> подразумевает список альтернатив. Это простая коллекция
без ограничений, однако подразумевается, что все ее элементы являются
альтернативами в смысле, зависящем от конкретного приложения. Так, в
контейнере <Alt> могут содержаться варианты одного и того же
сообщения программы на разных языках.
Эти контейнеры позволяют организовывать субъекты и объекты в группы, а также компактно записывать несколько сходных фактов. В контейнерах всех трех типов могут встречаться повторяющиеся элементы.
Контейнеры содержат элементы, каждый из которых заключен в тег <li>, подобно элементам списков <UL> и <OL> в языке
HTML. Каждый элемент контейнера является объектом. Поскольку объект в
<Description>,
контейнеры могут быть вложенными. В листинге 11.9 приведен пример
простого контейнера.
<Description about="www.example.com/#Том">
<ns:Владелец>
<Bag ID="Собаки">
<li>Спот</li>
<li>Фидо</li>
<li>Цербер</li>
</Bag>
</ns:Владелец>
</Description>
Смысл этой записи прозрачен: Том – владелец
<- "www.example.com/#Том", ns:Владелец, "Собаки" -> <- "Собаки", rdf:_1, "Спот" -> <- "Собаки", rdf:_2, "Фидо" -> <- "Собаки", rdf:_3, "Цербер" ->
<Description>, этот
Однако для того, чтобы этот подход мог работать, необходимо решить две проблемы. Во-первых, новому субъекту требуется идентификатор или, по крайней мере, соответствующий ему литерал. Кроме того, у вновь создаваемых фактов, помимо субъекта и объекта, должны быть также предикаты (имена свойств).
Первая проблема решается просто – создатель документа должен
снабдить тег-контейнер атрибутом ID или about. В противном случае
контейнер будет анонимным, а документ
Вторая проблема решается в процессе интерпретации документа _1, _2, _3. Поскольку эти имена относятся к пространству
имен , и т.д., при условии, что
префикс присвоен этому пространству имен. Таково происхождение
предикатов, использованных в листинге 11.10.
в листинге 11.11 представлены факты, эквивалентные записи в
листинге 11.9 (т.е. порождающие в хранилище фактов ту же структуру при
интерпретации документов
<Description about="www.test.com/#Том"> <ns:Владелец resource="Собаки"/> </Description> <Description about="Собаки" rdf:_1="Спот"/> <Description about="Собаки" rdf:_2="Фидо"/> <Description about="Собаки" rdf:_3="Цербер/>
Для факта с предикатом < использована сокращенная
запись, поскольку объектом является литерал. Мы не можем использовать
аналогичную форму записи для первого факта, поскольку его объект,
"Собаки", в данном случае рассматривается как фрагмент URL,
а не как литерал. Использовать или не использовать контейнеры – выбор
разработчика, однако они, как правило, выглядят аккуратнее, чем
эквивалентный набор тегов <Description>.
Все эти факты хранятся во внутреннем представлении документа
Тег-контейнер может иметь следующие атрибуты:
ID type
Атрибут ID аналогичен тому же атрибуту тега <Description>.
Значение атрибута type не определяется автором документа. Оно
автоматически устанавливается равным имени тега-контейнера (например, ), которое и считается типом данного тега. Эта пара
атрибут-значение образует отдельный факт, субъектом которого является значение
атрибутов about или ID тега-контейнера. Однако считается, что
предикатом этого факта является не type, а специальное значение instanceOf. В примере с тремя собаками этот факт имеет следующий
вид:
<- "Собаки", http://www.w3.org/1999/02/22-rdf-syntax-ns#instanceOf, http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag ->
С помощью данного факта разработчик приложения может определить контейнер и установит его тип. Однако в случае Mozilla необходимости в этом, как правило, не возникает, поскольку платформа предоставляет удобные вспомогательные объекты.
В тегах-контейнерах также может использоваться та же общая форма
сокращенной записи "свойство = значение", что и в теге <Description>. Для тега <li> определены следующие
атрибуты:
parseType resource
Они аналогичны соответствующим атрибутам тегов-предикатов и допускают те же формы сокращенной записи.
На этом мы заканчиваем обсуждение синтаксиса
В этом разделе представлено несколько примеров практического
применения
Менеджер загрузок классического браузера представляет собой
наглядный пример использования документа Навигатор
| Загрузки диалогового окна настроек Mozilla ( пункт меню Правка |
Настройки ).
Интерфейс Менеджера загрузок состоит из единственного окна XUL, а
данные о загрузках хранятся в файле Файл | Сохранить как. Кроме того,
Менеджер загрузок можно открыть в любой момент при помощи пункта меню Инструменты | Менеджер загрузок. Файл <tree>.
Чтобы пронаблюдать работу программы с файлом <Seq>, как
показано в листинге 11.12.
<?xml version="1.0"?> <RDF:RDF xmlns:NC="http://home.netscape.com/NC-rdf#" xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > <RDF:Seq about="NC:DownloadsRoot"> </RDF:Seq> </RDF:RDF>
Затем откройте любую страницу на удаленном сервере, например
http://www.mozilla.org. Сохраните страницу в локальном файле и, когда
сохранение будет полностью завершено, перезагрузите файл downloads.<Description> с содержимым, а также элемент коллекции <Seq>. Тег <Description> содержит восемь фактов о
загруженном файле. Примечательно, что эти факты записаны с помощью
различных видов нотации. Субъект факта с тегом <Description>
одновременно является объектом в коллекции <Seq>. Эта коллекция
позволяет найти все записи о файлах, включенные в документ.
Файл downloads.
<?xml version="1.0"?>
<RDF:RDF
xmlns:NC="http://home.netscape.com/NC-rdf#"
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
<RDF:Seq about="NC:DownloadsRoot">
<RDF:li resource="C:\tmp\test_save.html"/>
</RDF:Seq>
<RDF:Description about="C:\tmp\test_save.html"
NC:Name="test_save.html"
NC:ProgressMode="none"
NC:StatusText="Finished"
NC:Transferred="1KB of 1KB">
<NC:URL resource="http://www.mozilla.org/"/>
<NC:File resource="C:\tmp\test_save.html"/>
<NC:DownloadState NC:parseType="Integer">1</NC:DownloadState>
<NC:ProgressPercent NC:parseType="Integer">100</NC:ProgressPercent>
</RDF:Description>
</RDF:RDF>
При использовании Microsoft Windows локальные пути записываются с
префиксом C: (или другим именем диска). Это расширение синтаксиса URL,
используемое компанией Microsoft, поддерживается Mozilla. Такая запись
эквивалентна префиксу file:///C| / и, с точки зрения Mozilla, допустима
в составе URL.
Попробуйте сохранять другие страницы, наблюдая изменения в файле.
Также можно, закрыв окно Менеджера загрузок, аккуратно удалить из
файла один из элементов контейнера <Seq> и соответствующий тег <Description>. Затем следует вновь открыть окно и посмотреть на
результат.
Менеджер загрузок мог бы быть реализован без использования
Выше мы уже обсуждали некоторые типы, используемые в документах
Типы литералов: . Тип XMLLiteral не поддерживается.
Типы компонентов фактов: Property, . Тип List не
поддерживается.
Типы фактов: тип Statement не поддерживается.
Типы, используемые для , и object
не поддерживается.
Тип используется для хранения массива бинарных данных. Этот
тип нельзя указать из скрипта JavaScript – это расширение Mozilla,
которое может быть использовано только из кода на C/C++. Литералы типа используются, в частности, в
Типы, поддерживаемые в документах type тега <Description>, что эквивалентно использованию
встроенного тега-предиката <.
Платформа Mozilla не поддерживает типов
До сих пор при обсуждении идентификаторов в этой лекции мы
использовали в качестве примеров только URL. Этот формат
идентификатора полезен при хранении информации о web-сайтах и других
ресурсах Internet. Однако если приложение должно работать с простыми
данными, вместо URL рекомендуется использовать
Строго говоря, идентификаторы в
URL связывает ресурс с точкой доступа к нему (адресом) и методом
доступа, например протоколом HTTP. Ресурс, доступный по указанному
адресу, например web-страница, может меняться со временем.
С точки зрения программиста,
urn:{namespace}:{name}
Как {namespace}, так и {name} представляют собой строку. Строка {namespace} не может иметь значения "{name} может содержать любые символы ASCII,
включая двоеточие, что поначалу может показаться странным. Точный
синтаксис {name}
может также содержать знаки пунктуации и тоже нечувствительно к
регистру. Существуют некоторые ограничения на допустимые знаки
пунктуации. {name} является необязательной. Вот два примера корректных
urn:myapp:runstate urn:myapp:perfdialog:response
Во втором {name} выглядит так, как если бы она содержала
второе пространство имен, вложенное в первое, и собственно имя. С
точки зрения формального синтаксиса это лишь видимость – перед нами
обычное имя, содержащее символ двоеточия. Однако программисты могут
использовать этот пример для того, чтобы упорядочить большое
количество
Вот пример факта, записанного на языке
<Description about="urn:mozilla:skin:modern/1.0" chrome:author="mozilla.org"/>
Здесь : представляет собой префикс пространства имен XML,
"mozilla.org" – литерал, а "
mozilla["skin:modern/1.0"].author = "mozilla.org";
Или, чуть более подробно:
urn.mozilla.skin["modern/1.0"].chrome.author = "mozilla.org";
Разумеется, факт в общем случае не сводится к операции присваивания, так что эти примеры отражают лишь один из возможных способов интерпретации приведенного факта.
Существует специальная "data:" ), предназначенная для представления
обычных данных в виде URL и описанная в документе
Типы Правка | Настройки | Навигатор |
Вспомогательные приложения.
Как и Менеджер загрузок, система настройки типов pref-application.
Эту подсистему Mozilla можно изучать так же, как и Менеджер
загрузок. Разница между ними в том, что
urn:mimetypes urn:mimetypes:root urn:mimetypes:text/plain urn:mimetypes:application/octet-stream urn:mimetypes:handler:text/plain urn:mimetypes:handler:application/octet-stream urn:mimetypes:externalApplication:text/plain urn:mimetypes:externalApplication:application/octet-stream
Поскольку
Как и в случае с Менеджером загрузок, вся информация о типах
находится в контейнере <Seq>, который обеспечивает легкий доступ
к ней. Если одновременно открыто несколько окон браузера и загружается
содержимое различных типов, все эти окна пользуются одним и тем же
источником данных
Mozilla использует технологии
Согласно спецификации
Наиболее известным результатом деятельности в этом направлении
является так называемое "Дублинское ядро" (
Еще одна область применения
В реальности существует целый ряд механизмов "управления
содержимым" в указанном смысле, и
Область, в которой
Пока
На этом мы заканчиваем обсуждение примеров применения
Это практическое занятие посвящено процессу моделирования,
результатом которого является набор фактов
Мы много экспериментировали с интерфейсом NoteTaker и скриптами
JavaScript, однако пришло время заняться проектированием. У нас до сих
пор нет ясного понимания того, какими данными должен манипулировать
NoteTaker. Мы выбираем
На платформе Mozilla
Выбор фактов в качестве
При разработке и реализации
Как правило, при моделировании данных приходится предпринять несколько попыток, прежде чем будет найден оптимальный вариант. Мы, однако, сразу же начнем с приемлемого подхода, обращая в процессе моделирования внимание на некоторые распространенные ошибки и тупиковые направления.
Мы можем без труда описать
Ключевые слова – обычные слова, добавляемые пользователем для характеристики URL, к которому относится заметка. Если два ключевых слова были использованы для описания одной заметки, говорят, что эти слова связаны. Эта связь имеет значение и за пределами конкретной заметки – тот факт, что они появились вместе в каком-либо контексте, указывает на то, что эти слова связаны в широком смысле. Связи между ключевыми словами могут использоваться для контекстно-зависимой подсказки пользователю. Когда последний выбирает ключевое слово для заметки, одновременно отображается список всех слов, связанных с выбранным. Пользователь может отметить некоторые слова в этом списке, чтобы присвоить их заметке одновременно с первым.
В приложение NoteTaker, которое разрабатывается в этой книге, будет
включен лишь минимум функциональности, связанной с ключевыми словами,
для демонстрации некоторых приемов работы с XUL и
Интерфейс NoteTaker включает еще два элемента данных, которые отображаются как флажки "Отбросить запрос" и "Корневая страница" в диалоговом окне редактирования заметки. Эти данные не являются свойствами заметки, а скорее управляют процессом ее создания.
Если установлен флажок "Отбросить запрос", то из URL новой заметки будет удалена любая информация, относящаяся к запросу GET. Например, этот URL
http://www.test.com/circuits.cgi?voltage=240V;amps=50mA
будет сокращен до следующего
http://www.test.com/circuits.cgi
При этом вновь созданная заметка будет появляться при просмотре любой страницы, чей URL начинается с этой сокращенной строки. Если установлен флажок "Корневая страница", то URL будет сокращен еще больше, до
В этом случае заметка будет соответствовать всем страницам данного сайта. Если URL содержит каталог отдельного пользователя, как в примере:
http://www.test.com/~fred/mytests/test2.htm
то при установленном флажке "Корневая страница" он будет сокращен
При использовании любого из этих вариантов при просмотре
конкретного URL будет отображаться только наиболее специфичная для
него заметка. Иными словами, если одновременно определены заметка для
корневой страницы сайта и заметка для другой его страницы, то при
просмотре этой страницы будет отображаться лишь последняя заметка. В
любом случае, наличие этих флажков никак не влияет на
На этом выполнение первого этапа нашего плана завершено, и мы можем
перейти ко второму. В результате процесса моделирования все наши
данные должны быть представлены в виде фактов-триплетов. Пока же мы
должны выбрать из описания значимые термины, которые в дальнейшем
станут
заметка ключевое-слово URL аннотация подробности сверху слева высота ширина
Здесь "сверху" и "слева" – расстояние левого верхнего угла заметки от верхнего и левого краев экрана соответственно. К этим существительным мы можем добавить следующие предполагаемые отношения:
связанное-ключевое-слово данные-заметки заметка-для-url
Теперь мы должны сконструировать факты на основе этих терминов.
Факты могут рассматриваться как триплеты субъект-предикат-объект или,
в терминологии
Третий вопрос поможет нам выявить "слабые" термины, чтобы ограничить число субъектов в нашей модели. Результаты анализа представлены в таблице 11.4 (цифры указывают на пункты обсуждения в последующем тексте).
| Термин | Сущность? | Отношение? | Свойство? |
|---|---|---|---|
| заметка | V | V 3. | |
| ключевое-слово | V | 1. | |
| URL | V | V 3. | |
| аннотация | 2. | V | |
| подробности | 2. | V | |
| сверху | 2. | V | |
| слева | 2. | V | |
| ширина | 2. | V | |
| высота | 2. | V | |
| связанное-ключевое-слово | V | V | |
| данные-заметки | V 4. | ||
| заметка-для-url | V | V |
На основе этого анализа мы можем сделать некоторые выводы, а ряд вопросов требует дополнительного обсуждения. Начнем с выводов: ключевое-слово представляет собой сущность; данные-заметки – отношение; аннотация, подробности, сверху, слева, ширина и высота – свойства для описания других сущностей. Мы можем быть уверены в этом, поскольку в каждой из соответствующих строк таблицы присутствует лишь одна отметка.
Теперь обсудим проблемы, возникшие при анализе терминов.
1. Мы полагаем, что конкретные ключевые слова не могут
рассматриваться как свойства другого термина, поскольку это означало
бы, что на основе этих ключевых слов должны быть образованы свойства
2. Эти термины не имеют собственных свойств, поэтому нет оснований считать их самостоятельными сущностями. Очевидно, они являются свойствами каких-то других сущностей, например URL или заметки.
3. Нам не вполне ясна ситуация с заметкой и URL. Является ли один из этих терминов свойством другого или же они независимы? Пока лучше считать, что оба термина – сущности.
4. Смысл такого термина, как "данные заметки" не вполне
ясен. Он не указывает ни на конкретные данные, ни на отношение между
ними, ни на какую-либо другую определенную информацию. Можно сравнить
этот неопределенный термин с "аннотацией", которая является
конкретным фрагментом данных, связанным с заметкой. Фактически мы
невольно привнесли в нашу модель
На основе нашего анализа мы можем сформулировать факты, перечисленные в листинге 11.15.
<- заметка, ?, URL -> <- URL, ?, заметка -> <- заметка, URL, ? -> <- URL, заметка, ? -> <- ключевое-слово, ?, ? -> <- заметка, аннотация, ? -> <- заметка, подробности, ? -> <- заметка, сверху, ? -> <- заметка, слева, ? -> <- заметка, ширина, ? -> <- заметка, высота, ? -> <- ?, связанное-ключевое-слово, ? -> <- ?, заметка-для-url, ? ->
Первые четыре факта представляют собой четыре варианта разрешения неопределенности, с которой мы столкнулись. Мы должны сделать выбор, исходя из потребностей приложения. Мы вернемся к этой проблеме после того, как разберем более простые вопросы.
Шесть следующих фактов с субъектом "заметка" тривиальны.
Каждый из них будет содержать в качестве объекта простое значение,
следовательно, этим объектом не может быть ). Мы будем использовать тип , который
представляет собой простую строку. Тогда эти факты примут следующий
вид:
<- заметка, аннотация, Literal ->
Факт с предикатом связанное-ключевое-слово связывает между собой два ключевых слова. Очевидно, что субъектом и объектом этого факта должны быть ключевые слова. Заменив для краткости предикат на "связано", получаем следующий факт:
<- ключевое-слово, связано, ключевое-слово ->
Использование ключевых слов в фактах создает проблему имен. Нам
известно, что ключевое слово должно быть представлено посредством : (мы используем английское слово
" будет присвоен следующий
urn:notetaker:keyword:foo
Нам также понадобится доступ к самой строке ключевого слова. В
последующих лекциях мы увидим, что извлечь подстроку из
<- urn:notetaker:keyword:{строка ключевого слова},
метка, "{строка ключевого слова}" ->
Наконец мы должны разобраться с вопросом о соотношении заметки и URL. Каждому URL соответствует одна заметка, и каждой заметке соответствует один URL. Необходимо решить, являются ли они отдельными сущностями. Если это так, нам понадобится каким-то образом описать связь между ними. Если их нельзя рассматривать как отдельные сущности, то одна из них, вероятно, будет свойством другой.
Если считать URL и заметку отдельными сущностями, каждая из них
должна иметь собственный
Таким образом, мы приходим к выводу, что заметке недостает собственной идентичности, и она должна каким-то образом зависеть от URL. Поскольку заметка не имеет идентичности (не может быть поименована), она не может быть субъектом или объектом никакого факта. Поскольку она не имеет "собственного значения", она не может быть представлена литералом. Таким образом, заметка как сущность, самостоятельная или зависимая, просто не существует. Мы исключаем ее из нашей модели, оставляя только URL, к которому относится эта заметка. Это решает большинство проблем, связанных с первыми четырьмя фактами листинга 11.15.
Такой результат может показаться странным, особенно для читателя,
который знаком с объектно-ориентированным или реляционным
моделированием. Разве заметка не является центральным объектом всего
приложения NoteTaker? Разве мы не вправе создавать в нашей модели
любые объекты или сущности, которые сочтем необходимыми? Ответ на
первый вопрос – "да", а на второй – "нет". Да,
заметка действительно является центром приложения, но, как выяснилось,
не его
Итог этого рассуждения прост – чтобы использовать сущность в модели
данных
В листинге 11.16 представлены факты после произведенных нами изменений:
<- URL, аннотация, Literal -> <- URL, подробности, Literal -> <- URL, сверху, Literal -> <- URL, слева, Literal -> <- URL, ширина, Literal -> <- URL, высота, Literal -> <- ключевое-слово, метка, Literal -> <- ключевое-слово, связано, ключевое-слово ->
Очевидно, что в этом списке отсутствует факт связи между ключевым
словом и заметкой (точнее, с URL, которому соответствует заметка). Мы
не затрагивали этой связи в процессе анализа, поскольку нам не было
ясно, являются ли ключевые слова сущностями или свойствами. Мы не
можем использовать конкретные ключевые слова в качестве свойств
(предикатов), поскольку каждое ключевое слово имеет свой
<- URL, ключевое-слово, urn-ключевого-слова -> <- urn-ключевого-слова, url-заметки, URL->
Каждому URL (и заметке) может соответствовать ноль или более фактов первого типа. Вместо этого (или в дополнение к этому), каждому ключевому слову может соответствовать ноль или более фактов второго типа.
В предлагаемом решении каждая заметка (каждый URL) может иметь
несколько свойств "ключевое слово". Можем ли мы использовать
для их хранения контейнер <Seq>? К сожалению, это
не так просто. Пойдя по такому пути, мы должны будем использовать
отдельный контейнер для каждого URL с определенной заметкой. Какое имя
должен иметь такой контейнер? Это должен быть <Seq>. Мы будем
использовать первый из предложенных вариантов:
<- URL, ключевое-слово, urn-ключевого-слова ->
Таким образом, мы завершили третий и четвертый этапы нашего плана –
выразили всю необходимую информацию о
<- http://saturn/test.html, аннотация, "Моя аннотация" -> <- http://saturn/test.html, подробности, "Мои подробности" -> <- http://saturn/test.html, сверху, "100" -> <- http://saturn/test.html, слева, "90" -> <- http://saturn/test.html, ширина, "80" -> <- http://saturn/test.html, высота, "70" -> <- http://saturn/test.html, ключевое-слово, urn:notetaker:keyword:test -> <- http://saturn/test.html, ключевое-слово, urn:notetaker:keyword:cool -> <- urn:notetaker:keyword:test, метка, "test" -> <- urn:notetaker:keyword:cool, метка, "cool" -> <- urn:notetaker:keyword:test, связано, urn:notetaker:keyword:cool ->
Последний факт выражает связь между ключевыми словами. Мы могли бы сформулировать и обратный факт, поменяв местами субъект и объект. Однако в этом случае мы получили бы множество избыточных фактов для заметки со множеством ключевых слов. Поэтому здесь мы ограничились минимумом фактов, необходимых для описания связи между ключевыми словами.
Пятый и шестой этапы нашего плана связаны с эффективностью доступа
к необходимым данным документов
Мы хотим, чтобы помимо выполнения этих видов поиска, приложение могло легко и быстро добавлять, удалять и изменять заметки. Эти задачи достаточно просты, поэтому мы сосредоточимся на приведенном списке, который фактически представляет собой набор запросов.
Mozilla может находить факты в документе
<Bag >, имеющий urn :notetaker:notes. При выполнении запросов 1, 2 и 3 этот контейнер может использоваться для облегчения поиска заметки и ее данных.<bag >, имеющий urn :notetaker:keywords . Запрос 4 сможет использовать этот контейнер для получения списка ключевых слов.Запрос 5 очень сложен, поскольку он требует просмотра большого количества фактов, имеющих отношение к ключевым словам. На данном этапе мы вряд ли можем предпринять что-либо для ускорения этого запроса. Как бы он ни выполнялся, для этого понадобится посмотреть все факты о связях между ключевыми словами или большую их часть.
Поскольку предполагается, что в документе < и другие
теги-контейнеры представляют собой субъекты фактов, мы добавим тег
верхнего уровня <Description>, имеющий .
Оба наших контейнера < будут значениями свойств этого
тега.
К этому и сводится все необходимое нам моделирование. Седьмой этап
плана представляет собой механическое преобразование
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmnls:NT="http://www.mozilla.org/notetaker-rdf#>
<Description about="urn:notetaker:root">
<NT:notes>
<Seq about="urn:notetaker:notes"/>
</NT:notes>
<NT:keywords>
<Seq about="urn:notetaker:keywords"/>
</NT:keywords>
</Description>
</RDF>
Если добавить к этому документу факты о заметке, представленные в
листинге 11.17, результатом
будет документ, представленный в листинге
11.19
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmnls:NT="http://www.mozilla.org/notetaker-rdf#>
<Description about="urn:notetaker:root">
<NT:notes>
<Seq about="urn:notetaker:notes">
<li resource="http://saturn/test.html"/>
</Seq>
</NT:notes>
<NT:keywords>
<Seq about="urn:notetaker:keywords">
<NT:keyword resource="urn:notetaker:keyword:cool/>
<NT:keyword resource="urn:notetaker:keyword:test/>
</Seq>
</NT:keywords>
</Description>
<!-- одна заметка -->
<Description about="http://saturn/test.html">
<NT:summary>Моя аннотация<NT:summary/>
<NT:details>Мои подробности<NT:details/>
<NT:top>100<NT:top/>
<NT:left>90<NT:left/>
<NT:width>80<NT:width/>
<NT:height>70<NT:height/>
<NT:keyword resource="urn:notetaker:keyword:test"/>
<NT:keyword resource="urn:notetaker:keyword:cool"/>
</Description>
<!-- строки ключевых слов -->
<Description about="urn:notetaker:keyword:test label="test"/>
<Description about="urn:notetaker:keyword:cool label="cool"/>
<!-- связи между ключевыми словами, пока есть одна -->
<Description about="urn:notetaker:keyword:test">
<NT:related resource="urn:notetaker:keyword:cool">
</Description>
</RDF>
Некоторые теги <NT: повторяются в этом файле. При
разработке всегда существует выбор между простотой данных и простотой
системы, которая должна делать запросы к этим данным. В данном случае
мы допустили некоторое
Таким образом, мы завершили работу над
Как правило, обработка данных
Документы
Если вы из какого-либо скрипта модифицируете источник данных
Автоматическое построение графа произвольного
Если вы не знаете точно, в каком состоянии находится ваше хранилище фактов (например, вы многократно модифицировали его из своей программы), существует легкий способ записать его текущее состояние на диск. Для этого используется код, приведенный в листинге 11.20.
// подготовка ..
var Cc = Components.classes;
var Ci = Components.interfaces;
var comp = Cc["@mozilla.org/rdf/rdf-service;1"]
var iface = Ci.nsIRDFService;
var svc = comp.getService(iface);
var ds = svc.GetDataSource("file:///C|/tmp/test.rdf");
var rds = ds.QueryInterface(Ci.nsIRDFRemoteDataSource);
// .. обычная работа с хранилищем фактов ..
function dumpRDF()
{
// чтобы произошла запись в файл, должно быть
сделано хотя бы одно изменение
var sub = svc.GetResource("urn:debug:subject");
var pred = svc.GetResource("DebugProp");
var obj = svc.GetResource("urn:debug:object");
ds.Assert(sub, pred, obj, true);
rds.Flush(); // записать в файл
}
Этот код создает источник данных dumpRDF() может быть вызвана в любой момент
после завершения загрузки источника (это можно проверить при помощи
флага или используя объект-наблюдатель). Функция dumpRDF()
всего лишь добавляет один факт к хранилищу фактов и записывает текущее
состояние хранилища в исходный файл. Иными словами, файл
синхронизируется с состоянием хранилища в памяти. Факт добавляется
для того, чтобы состояние хранилища гарантированно изменилось, и
произошла запись на диск. При просмотре файла этот факт будет
выглядеть примерно следующим образом:
<RDF:Description about="urn:debug:subject"> <DebugProp resource="urn:debug:object"/> </RDF:Description>
DebugProp и debug – простые строки, не имеющие специального
значения.
Системы обработки фактов отличаются от обычных систем обработки
данных. Для их понимания необходимо усвоить целый ряд новых терминов:
факт,
Внутри платформы Mozilla содержится ряд относительно тяжеловесных
структур и модулей, которые интенсивно обмениваются информацией в
процессе обработки и отображения содержимого. Каналы и источники
данных – разновидности таких структур, тесно связанные с
Внутри платформы
После всех сложностей
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.