Опубликован: 10.12.2007 | Уровень: специалист | Доступ: платный
Лекция 14:

Шаблоны

14.3.3. Тег <template>

Тег <template> содержит все детали информации о шаблоне, которые не были указаны в базовом теге. Он содержит набор правил, каждое из которых - пара запрос-контент. Тег <template> не имеет собственных атрибутов. Единственный тег, который он может содержать - тег <rule>. Зато он может содержать произвольное их число.

Если тегов <rule> нет, но есть иной контент, этот контент считается единственным правилом с синтаксисом для простых правил.

Тег <template> может содержать простые и расширенные правила.

14.3.4. Тег <rule>

Тег <rule> определяет единичный запрос шаблона и контент, генерируемый для оформления вывода результатов запроса. Несколько тегов <rule> формируют список запросов. Таким образом, первый тег <rule> будет формировать оформление результатов запроса.

Правила могут быть записаны с помощью простого и расширенного синтаксисов. Если первый дочерний тег тега <rule> - это тег <conditions>, правило должно быть записано в расширенном синтаксисе. В любом другом случае применим простой синтаксис. Тег <rule> может быть единственным тегом без какого-либо контента.

14.3.4.1. Стандартное устройство факта

Все запросы с простым синтаксисом и многие с расширенным основываются на фактах в RDF-файле, которые упорядочены определенным образом. Это упорядочение может повторяться. Это тот случай, когда RDF-данные имеют устройство "три ступени, два факта". Ступени - контейнер, его элементы и им принадлежащие пары свойство-значение. Листинги 14.1 и 14.2 и их обсуждение демонстрируют пример данного устройства.

Это стандартное устройство также эквивалентно

JavaScript: var container = {item1:{p1:v1,p2:v2}, item2:{p1:v1,p3:v3}}

В этой строке контейнер содержит два элемента. item1 и item2 - это объекты, каждый из которых имеет множество свойств pN. Каждое свойство имеет значение vN. Может быть любое число элементов, каждый с любым числом свойств. Суть такой структуры - дать легкий доступ ко множеству объектов и интересующим нас свойствам. Листинги 14.2, 14.5, 14.7, и 14.9 являются корректными примерами этой структуры в RDF. Листинг 14.11 показывает RDF-эквивалент структуры, описываемой строкой JavaScript.

<Seq about="container"> 
<li resource="item1"/> 
<li resource="item2"/> 
</Seq> 
<Description about="item1" p1="v1" p2="v2"/>
<Description about="item2" p1="v1" p3="v3"/>
Листинг 14.11. RDF структура для RDF правила с простым синтаксисом

Чтобы сделать RDF синтаксис яснее, тег <Seq> обычно заворачивают в тег <Description>, не показанный в листинге 14.11. RDF имеет гибкий синтаксис, и существует несколько других путей выразить ту же самую структуру. Тег <Seq> может быть, кроме того, заменен на <Bag> или <Alt>. Вместо них можно использовать тег <Description> в роли контейнера.

Все факты, которые обрабатываются запросом с простым синтаксисом, должны иметь это стандартное устройство.

14.3.4.2. Простой синтаксис тега <rule>

Простой синтаксис тега <rule> не имеет специальных тегов.

Весь контент тега <rule> генерируется каждый раз, когда запрос находит решение. Контент тега <rule> может содержать простые переменные шаблона, помещенные в любое значение атрибута XML. Контент генерируется так же, как для тега <action>, за исключением двух незначительных отличий: простой синтаксис требует, чтобы атрибут uri имел значение rdf:*, и простой синтаксис не может использовать тег <textnode>.

Когда применяется простой синтаксис, тег <rule> имеет несколько специальных атрибутов:

type iscontainer isempty predicate="object" parsetype

Все эти атрибуты определяют, будет ли запрос правила успешен. Часть запроса определяется предположением, что RDF факты имеют стандартное устройство. Данные атрибуты определяют остальную часть.

Атрибут type взят из официального пространства имен RDF XML http://www.w3.org/1999/02/22-rdf-syntax-ns#.

Его обычно записывают как rdf:type, включая это пространство имен ранее где-либо в документе XUL с помощью xmlns. Можно указать rdf:type и с полным именем предиката, как http:// home.netscape.com/NC-rdf#version.

Этот атрибут используется для проверки существования предиката. То есть rdf:type проверяет, существует ли в контейнере объект, имеющий такое свойство. Если нет, данный кандидат на решение отбрасывается.

Атрибут iscontainer может иметь значение true или false. Значения по умолчанию нет. Он проверяет, является ли подлежащее данного факта контейнером, используя "тесты контейнера", описанные ранее в разделе "Атрибуты ref и containment: Тесты контейнера". Если тесты не проходят, правило отвергает данного кандидата на решение.

Атрибут isempty может иметь значение true или false. Значения по умолчанию нет. Он проверяет, содержит ли данный URI какую-либо разновидность контента. В случае значения true он проверяет, имеет ли подобный контейнеру URI какие-либо элементы содержания контейнера, а элементоподобный URI - какие-либо свойства. Если тест не проходит, правило отвергает данного кандидата на решение.

Атрибут predicate="object" означает любую пару имен предиката и дополнения. Поскольку имена предикатов зачастую длинны, их сокращают, добавляя xmlns-декларацию в начале XUL документа. Если это сделано, пара predicate="object" наподобие

NC:version="0.1"

проверяет, существует ли предикат version в пространстве имен NC (вероятно, http://home.netscape.com NC-rdf#) и имеет ли он дополнение со значением "0.1" - иными словами, имеет ли объект в контейнере свойство version со значением "0.1". Следующие зарезервированные имена не могут применяться для предиката, поскольку они используются иным образом:

property instanceOf id parsetype

Эти три атрибута, плюс любое число тестов predicate="object", могут содержаться в одном теге <rule>. Они соединены между собой булевым AND и относятся ко всем запросам правила. Если никакой из них не указан, то любой факт в контейнере является решением для запроса. Если любой из них присутствует, запрос не найдет решения, если хоть какой-то из этих атрибутов не удовлетворяется.

Последний атрибут, parsetype, может иметь значение Integer. Если это указано, во всех парах predicate="object" часть "объект" будет интерпретироваться как целое. Любое нецелое значение приведет к тому, что весь запрос будет проигнорирован. Если атрибут не используется, объектные части пар интерпретируются как строки. Система запросов не имеет встроенной математики для, например, складывания целых. Она лишь выясняет, целое перед ней или строка.

Запрос в простом правиле обычно может быть выражен и как расширенное правило. Листинг 14.12 - пример простого синтаксиса, использующего некоторые из специальных атрибутов.

<rule iscontainer="true" isempty="false"
  rdf:type="http://home.netscape.com/NC-rdf#version"
  NC:title="History" >
Листинг 14.12. Простой шаблонный запрос, демонстрирующий все опции.

Эквивалентный расширенный синтаксис приведен в листинге 14.13.

<rule>
<conditions> 
  <content uri="?uri"/> 
  <member container="?uri" child="?item"/> 
    <triple subject="?item 
      predicate="http://home.netscape.com/NC-rdf#version" 
       object="?version"/> 
    <triple subject="?item"
      predicate="http://home.netscape.com/NC-rdf#title" 
       object="History"/>
</conditions>
Листинг 14.13. Простой шаблонный запрос, демонстрирующий все опции.

Расширенный синтаксис может делать все то же, что и простой, за исключением опций iscontainer="false" и isempty="true" (значения, противоположные приведенным в примере в листинге 14.12). Эти две опции в расширенном синтаксисе невозможны. Расширенный синтаксис может проверить существование факта, но не его отсутствие. Эти простые проверки все же можно осуществить в расширенном синтаксисе, указывая два правила, а не одно. Первое правило проверяет наличие конкретного факта, но не генерирует контента, второе отбирает оставшиеся случаи, в которых контент отсутствует, и генерирует требуемый.

14.3.4.3. Расширенный синтаксис <rule>

Когда используется расширенный синтаксис, тег <rule> не имеет специальных атрибутов. Этот синтаксис - наиболее гибкий и мощный из всех синтаксисов шаблонов. В разделе "Часто встречающиеся образцы запросов" приведены рецепты для наиболее распространенных случаев. В данном же разделе описываются опции синтаксиса.

Расширенный синтаксис правил состоит из тега <rule> с двумя или тремя дочерними тегами. Тег <conditions> должен быть первым из дочерних тегов и должен содержать запрос правила. Тег <bindings> - необязательный средний тег, позволяющий создавать дополнительные переменные. Тег <action> содержит тот контент, который следует генерировать при каждом обнаружении решения. Эти теги рассматриваются каждый в своем подразделе.

Расширенный синтаксис правил использует расширенный синтаксис переменных, и эти переменные могут использоваться в дочерних тегах тега <template>. Обычно их помещают в теги определения колонок в списках и деревьях.

Рекурсивность запроса указывается только в теге <conditions>.

14.3.5. Тег <conditions>

Тег <conditions> содержит запрос шаблона, описанный расширенным синтаксисом. Этот тег не имеет собственных атрибутов. Если он присутствует, он должен быть первым тегом <rule>. Рекурсивность рекурсивного запроса полностью определяется контентом тега <conditions>.

Этот тег может содержать теги <content>, <triple> и <member>. Первым дочерним тегом должен быть <content>, и этот тег должен быть ровно один. Тег <content> должен также содержать по крайней мере один тег <member> или <triple>.

Тег <conditions> может содержать тег <treeitem>. Если шаблон основан на теге <tree>, то вместо тега <content> можно использовать <treeitem>. В этом случае он записывается и ведет себя точно так же. Нет никаких особенных причин поступать именно так, это всего лишь память "давно минувших дней". <treeitem> считается устаревшим, лучше использовать <content>, однако на старых версиях платформы следует использовать <treeitem>.

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

14.3.5.1. Тег <content>

Тег <content> должен быть первым дочерним тегом тега <conditions>. Он имеет единственный специальный атрибут:

uri

Это атрибут расширенной переменной шаблона. Данная переменная затем обосновывается значением атрибута ref базового тега шаблона. Это значение является стартовой точкой запроса. Если запрос рекурсивен, вместо атрибута ref используется атрибут uri родительского запроса. Тег <content> всегда имеет одну и ту же форму, так что обычно он выглядит вот так:

<content uri="?uri"/>

Атрибут uri также используется в дочерних тегах тега <action>. Переменная, употребленная как атрибут uri тега <content>, никогда не должна употребляться как значение атрибутов uri, появляющихся в контенте тега <action>. Если ее использовать таким образом, запрос в шаблоне не обнаружит решений, и никакого контента не будет порождено. Переменная, используемая в атрибуте uri тега <content>, может появляться в любом другом месте контента тега <action>.

Если шаблон основан на дереве, в версиях платформы младше 1.5 используется тег <treeitem>, вот так:

<treeitem uri="?uri"/>

Тег <treeitem> также может быть частью порождаемого контента. В этом случае он может присутствовать в теге <action>, но любой атрибут uri в качестве значения должен иметь переменную, отличную от ?uri.

14.3.5.2. Тег <triple>

Тег <triple> представляет один шаг (одну арку в графе RDF) в процессе запроса. Каждый использованный тег <triple> увеличивает число шагов на единицу, и также на единицу увеличивает число фактов, требуемых для решения. Тег <triple> используется для связи фактов с переменными и для обнаружения фактов. Тег <triple> имеет следующие специальные атрибуты, которые должны всегда присутствовать.

subject predicate object

subject может принимать значение расширенной переменной шаблона или URI.

predicate может принимать значение URI, то есть имя свойства/предиката.

object может принимать значение расширенной переменной шаблона, URI или быть строкой.

В атрибутах предиката нельзя использовать переменные.

Можно сконструировать последовательность тегов <triple> так, что они образуют логическое кольцо. Ни одна из этих возможностей не обрабатывается Mozilla корректно. Тег <triple> с нулевыми переменными бесполезен.

14.3.5.3. Тег <member>

Тег <member> используется для поиска элементов, содержащихся в теге-контейнере. Он имеет специальные атрибуты

container child

Атрибут container - это URI тега-контейнера. Атрибут child сравнивается с дополнениями фактов, имеющими подлежащим URI контейнера. Оба атрибута должны присутствовать, и обоим присваиваются расширенные переменные шаблона, вот так:

<member container="?uri" child="?item"/>

Поскольку искомые связи внутри RDF-контейнера - это просто единичные факты (имеющие rdf:_1 или что то подобное в качестве предиката), обычный тег <triple> может быть использован для поиска этих элементов. Тег <member> - попросту специализированная версия тега <triple>.

Преимущество, которое имеет тег <member> перед тегом <triple> состоит в том, что можно вообще не указывать предикат. Тег <member> может применять тесты контейнера, описанные ранее в разделе "Атрибуты ref и containment: тесты контейнера". Чтобы выполнить ту же работу с тегом <triple>, придется задействовать добавочный запрос, указывающий URI, который можно использовать как тест контейнера.

Хотя атрибут контейнера тега <member> часто содержит URI начальной точки запроса, в запросе можно использовать любой URI или расширенную переменную запроса.

Дмитрий Гуменюк
Дмитрий Гуменюк
Россия, Звенигород
Konstantin Grishko
Konstantin Grishko
Россия, Москва, Московский финансово-промышленный университет "Синергия", Москва