Россия, Звенигород |
Шаблоны
14.3.6. Тег <bindings>
Тег <bindings> - необязательная часть расширенного синтаксиса запроса. Он не имеет специальных атрибутов, и может содержать только теги <binding>. Теги <bindings> и <binding> постоянно используются в Mozilla, особенно в XBL. Между их применением в шаблонах и где угодно еще нет прямой связи. В терминах SQL, они являются реализацией инструкции "outer joins" и нулевых значений.
Тег <bindings> следовало бы называть <extra-groundings>, поскольку это вовсе не "привязка" в смысле XBL (или XPConnect или IDL или XPIDL). binding -переменная это просто добавочная переменная, которая может быть обоснована добавочным запросом. Это же значение имеет и тег <binding>.
Раздел правила <bindings> - это место, где можно поместить добавочные переменные, не ограничивая результатов <conditions> запроса. Сделать это очень просто. В секции <conditions> все переменные должны быть обоснованы, чтобы было найдено решение. Это решение передается в секцию bindings. Далее процессор запроса пытается обосновать все переменные, перечисленные в секции <bindings>. Если лишь некоторые из них удается обосновать, процессор просто присваивает остальным нулевые значения. Это значит, что решения <conditions> никак не ограничиваются переменными <bindings>. Фактически, секция <bindings> подобна RDBMS инструкции outer join - если что-то подходит, об этом сообщается, в противном случае вы получаете только то, что найдено по запросу.
Переменные в секции <bindings> должны быть расширенными переменными шаблона. Переменные из раздела <conditions> можно использовать здесь, но не наоборот. Чтобы секция <bindings> имела смысл, должна быть использована по крайней мере одна из переменных секции <conditions>.
14.3.6.1. Тег <binding>
Тег <binding> идентичен тегу <triple> по атрибутам и способу использования. Он отличается от <triple> только в правилах, применяемых для обоснования его переменных, как описано в разделе <bindings>.
14.3.7. Тег <action> и контент, порождаемый запросом с простым синтаксисом
Тег <action> используется в <rule> с расширенным синтаксисом запроса. Он дает контент, который будет генерироваться для каждого результата данного запроса. Контент правила <rule> с простым синтаксисом генерируется точно так же, как контент тега <action>. Здесь описывается система генерации.
Контент тега <action> состоит из обычных XUL тегов и расширенных переменных запроса. Система шаблонов замещает значение каждой переменной при генерации контента. Таким образом, переменные используются в теге <action>, хотя определяются и обосновываются в теге <conditions> (они определяются и обосновываются автоматически при простом синтаксисе). Система шаблонов добавляет атрибут id каждому тегу каждый раз, когда генерируется контент. Тег <action> не может включать тег <script>.
Контент тега <action> должен быть организован так, как показано в листинге 14.14
<action> // simple syntax: <rule> <box id="A"> <box id="B"> <box id="C" uri="?var"> // simple syntax: uri="rdf:*" <box id="D"/> <box id="E"> <box id="F"/> </box> </box> </box> </box> </action>Листинг 14.14. Пример иерархического контента <action>.
Мы используем этот пример, чтобы объяснить, что и как здесьработает. В общем случае теги могут вкладываться на произвольную глубину внутри <action>, и может быть использован любой XUL-код. Специальный случай шаблонов, основанных на деревьях, обсуждается отдельно.
Контент тега <action> делится на тег, содержащий атрибут uri, порождающие его теги и наследующие ему теги. В листинге 14.14 С содержит uri ; A и B - теги-предки; D, E и F - дочерние теги.
Теги-предки A и B порождаются лишь однажды, независимо от того, как много решений обнаружит запрос. Если переменные запроса (расширенные для контента <action>, простые для контента <rule> ) используются в A и B, они будут иметь значения, найденные в первом решении запроса. Если A и B имеют дочерние теги, эти теги могут быть неадекватны. Рекомендуется их избегать.
Тег C - начало повторяющегося контента, поскольку он имеет атрибут uri. И С, и его контент могут генерироваться как целое ноль и более раз. Чтобы контент был сгенерирован хоть один раз, должны быть выполнены два условия. Во-первых, запрос должен обнаружить хоть одно решение. Во-вторых, значение атрибута uri тега C в этом обнаруженном решении должно быть другим. Самый простой способ удостовериться, что это именно так - установить его в значение переменной, упоминаемой как дополнение в некотором кортеже. Примером может быть часть child тега <member>. В этом случае необходимо использовать ?item:
<member container="?seq" child="?item"/>
В наиболее общем случае, атрибуту uri должно быть присвоено значение подлежащего или дополнения, разные для каждого решения, обнаруженного запросом. Атрибут id принимает данное уникальное значение для каждого тега C во время генерации контента. Тег C не должен иметь дочерних тегов, это может привести к ошибке. Рекомендуется в данном случае дочерних тегов избегать.
Если требуется построение контента с задержкой ("ленивое"), тег C должен быть одним из следующих XUL-тегов:
<menu> <menulist> <menubutton> <toolbarbutton> <button> <treeitem>
Теги D, E, и F - обычные теги, генерируемые один раз на каждое найденное решение запроса. Они могут иметь дочерние теги и обширный собственный контент. Если эти теги имеют переменные шаблона, такие переменные будут замещены найденными решениями.
14.3.7.1. Контент шаблонов, основанных на теге <tree>
Контент шаблонов, основанных на теге <tree>, может нарушать правило, согласно которому теги-родители uri-тега генерируются лишь однажды.
Если шаблон основан на теге <tree>, каждый <treeitem> в финальном дереве может иметь тег <treechildren> как свой второй дочерний тег. Этот тег может содержать любое число поддеревьев. К счастью, контент тега <action> должен представлять единственную строку дерева. Конструктор шаблона, обрабатывающий тег <tree>, достаточно разумен, чтобы скопировать этот контент в каждое поддерево. Другими словами, он достаточно разумен, чтобы определить необходимость рекурсивного запроса. Контент тега <action> нужно прописать достаточно аккуратно, чтобы такая конструкция работала. Она показана в Листинге 14.15.
<action> <treechildren> //simple syntax: use <rule> <treeitem uri="?var"> //simple syntax: use uri="rdf:*" <treerow> ... any normal treerow content ... </treerow> </treeitem> </treechildren> </action>Листинг 14.15. Пример иерархического контента тега <action> для шаблона на теге <tree>.
Все теги в этой конструкции могут иметь добавочные атрибуты. Не следует использовать атрибут id для тега <treeitem>. Переменная ?var обычно соответствует переменной в дополнении тегов <member> или <triple>.
Данный синтаксис можно слегка изменить, и даже использовать такой шаблон внутри другого шаблона. Например, так, что тег <treeitem> порождается из одного источника RDF, а его дочерние теги <treechildren> - из другого. Подобные вложения следует тщательно тестировать, потому что они не используются широко и, следовательно, не являются достаточно надежными.
Шаблоны, основанные на деревьях, используют рекурсивные запросы. С каждым шагом рекурсии вглубь дерева фактов контент тега <action> перед uri-тегом удваивается. Это означает добавочную копию тега <treechildren>, см. листинг 14.15. Эта новая копия становится затем отправной точкой для всех решений, найденных новым запросом.
14.3.7.2. Тег <textnode>
И простые, и расширенные переменные могут появляться только в значениях атрибутов XML. Некоторые теги XUL порождают текстовое содержание между их открывающей и закрывающей частями. Например, тег <Description>.
Тег <textnode> предоставляет способ поместить переменную в контент, не являющийся атрибутом. Предположим, переменная ?var в некоторый момент содержит строку "red". Тогда строка
<tag> <textnode value="big ?var truck"/> </tag>
будет эквивалентна строке
<tag>big red truck</tag>
Тег <textnode> можно поместить в любое место внутри тега <action>. Тег <textnode> не может быть использован, если запрос задействует простой синтаксис. На данном теге мы завершим рассмотрение тегов шаблона.