Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

2 Пути адресации

Хотя пути адресации (location path) и не являются самой главной грамматической конструкцией языка (LocationPath - это частный случай Expr), они имеют самое большое значение, а потому будут описаны в первую очередь.

Каждый путь адресации может быть описан с помощью простого, но довольно громоздкого синтаксиса. Существует также ряд синтаксических аббревиатур для краткого обозначения основных случаев. Сперва в этой главе с помощью развернутого синтаксиса будет дано разъяснение семантики путей адресации. Затем будет показано, каким образом сокращенный синтаксис приводится к развернутому (см. [2.5 Сокращенный синтаксис]).

Ниже приводятся некоторые примеры путей адресации, использующих развернутый синтаксис:

  • child::para находит элемент para, являющийся непосредственным потомком узла контекста

  • child::* собирает все элементы, являющиеся непосредственными потомками узла контекста

  • child::text() собирает все текстовые узлы, являющиеся непосредственными потомками узла контекста

  • child::node() собирает все непосредственные потомки текущего узла контекста независимо от типа этих узлов

  • attribute::name в текущем узле контекста находит атрибут name

  • attribute::* собирает все атрибуты в текущем узле контекста

  • descendant::para среди потомков узла контекста находит элементы para

  • ancestor::div собирает все предки div текущего узла контекста

  • ancestor-or-self::div собирает предки div текущего узла контекста и также, если сам узел контекста тоже является элементом div, включает в набор и его

  • descendant-or-self::para среди потомков узла контекста выбирает элементы para а также, если сам узел контекста является элементом para, то включает в набор и его

  • self::para выбирает текущий узел контекста, если это элемент para, либо в противном случае не выбирает ничего

  • child::chapter/descendant::para выбирает элементы para среди потомков элемента chapter, являющегося непосредственным потомком текущего узла контекста

  • child::*/child::para собирает все para, являющиеся потомками текущего узла контекста во втором поколении

  • / находит корень документа (который всегда является родителем элемента документа)

  • /descendant::para в документе, которому принадлежит узел контекста, находит все элементы para

  • /descendant::olist/child::item находит все элементы item, которые имеют родителем olist и находятся в пределах документа, в котором располагается узел контекста

  • child::para[position()=1] находит первый непосредственный потомок para текущего узла контекста

  • child::para[position()=last()] находит последний непосредственный потомок para текущего узла контекста

  • child::para[position()=last()-1] находит предпоследний непосредственный потомок para текущего узла контекста

  • child::para[position()>1] среди непосредственных потомков текущего узла контекста собирает все para, за исключением первого

  • following-sibling::chapter[position()=1] находит следующий chapter, имеющий с узлом контекста общего родителя

  • preceding-sibling::chapter[position()=1] находит предыдущий chapter, имеющий с узлом контекста общего родителя

  • /descendant::figure[position()=42] находит в документе сорок второй элемент figure

  • /child::doc/child::chapter[position()=5]/child::section[position()=2] находит второй section в пятом chapter в элементе документа doc

  • child::para[attribute::type="warning"] находит все непосредственные потомки para текущего узла контекста, имеющие атрибут type со значением warning

  • child::para[attribute::type='warning'][position()=5] среди непосредственных потомков текущего узла контекста с названием para и имеющих атрибут type со значением warning находит пятый элемент

  • child::para[position()=5][attribute::type="warning"] среди непосредственных потомков para узла контекста выбирает пятый элемент, при условии что он имеет атрибут type со значением warning

  • child::chapter[child::title='Introduction'] среди непосредственных потомков chapter текущего узла контекста выбирает тот, у которого в свою очередь имеется один или несколько непосредственных потомков title со строковым значением Introduction

  • child::chapter[child::title] среди непосредственных потомков текущего узла контекста chapter находит тот, у которого имеется один или несколько непосредственных потомков title

  • child::*[self::chapter or self::appendix] среди непосредственных потомков текущего узла контекста находит chapter и appendix

  • child::*[self::chapter or self::appendix][position()=last()] из множества непосредственных потомков текущего узла контекста chapter и appendix выбирает последний

Пути адресации бывают двух типов: относительные и абсолютные.

Относительный путь адресации состоит из последовательности одного или нескольких шагов адресации, отделенных друг от друга символом /. Шаги в относительном пути адресации считаются слева направо. На каждом шаге осуществляется отбор узлов, отталкиваясь от некоторого узла контекста. Основная последовательность шагов образуется последовательным перечислением шагов в порядке их выполнения. Сперва, отталкиваясь от узла контекста, последовательность шагов набирает некий набор узлов. Затем каждый узел в этом наборе поочередно используется как узел контекста для следующего шага. Все наборы узлов, полученных после выполнения такого шага, опять собираются вместе. В итоге в полученном объединении будет собран набор узлов, идентифицируемых данной последовательностью шагов. Например, формула child::div/child::para собирает все элементы para, являющиеся непосредственными потомками элемента div, который сам является непосредственным потомком узла контекста, или, иными словами, находит все элементы - потомки во втором поколении para, родителями которых являются div.

Абсолютный путь адресации состоит из символа /, за которым может следовать относительный путь адресации. Сам символ / находит корневой узел документа, в котором располагался текущий узел контекста. Если за этим символом последовал относительный путь адресации, то получившийся путь адресации будет собирать набор узлов так, как если бы в качестве узла контекста был выбран корневой узел того документа, которому принадлежал действительный текущий узел контекста.

Пути адресации
[1]    LocationPath    ::=    RelativeLocationPath
| AbsoluteLocationPath
[2]    AbsoluteLocationPath    ::=    '/' RelativeLocationPath?
| AbbreviatedAbsoluteLocationPath
[3]    RelativeLocationPath    ::=    Step
| RelativeLocationPath '/' Step
| AbbreviatedRelativeLocationPath

2.1 Шаги адресации

Шаги адресации (location step) состоят из трех частей:

  • оси (axis), указывающей дерево взаимоотношений между текущим узлом контекста и узлами, отбираемыми на данном шаге адресации,

  • правила проверки узлов, указывающего тип и расширенное название узлов, отбираемых на данном шаге адресации,

  • нуля или более предикатов, использующих произвольные выражения для дальнейшего отсева в наборе узлов, собранных на данном шаге адресации.

Синтаксис шага адресации образуется из названия оси и правила проверки узлов, отделенных друг от друга двумя символами двоеточия. За ними следует нуль или более выражений, каждое из которых заключено в квадратные скобки. Например, в выражении child::para[position()=1] фрагмент child - это название оси, para - правило проверки узла, а [position()=1] - предикат.

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

Исходный набор узлов образуется из узлов, имеющих с текущим узлом контекста взаимосвязь, определяемую указанной осью, имеющих тип узла и расширенное имя, отвечающих представленному правилу проверки узлов. Например, шаг адресации descendant::para находит элементы para, являющиеся потомками текущего узла контекста: descendant указывает, что каждый узел в первоначальном наборе должен быть потомком текущего узла контекста, а para указывает, что каждый узел в исходном наборе должен быть элементом с названием para. Можно использовать оси, описаные в главе [2.2 Оси]. Возможные правила проверки описаны в главе [2.3 Проверка узлов], причем смысл некоторых правил проверки меняется в зависимости от используемой оси.

Полученный исходный набор узлов фильтруется в соответствии с первым предикатом для получения нового набора узлов, затем этот новый набор фильтруется в соответствии со вторым предикатом и так далее. Окончательный набор узлов и будет тем самым набором, который получен в результате выполнения данного шага адресации. Выбранная ось оказывает влияние на обработку выражения для каждого предиката, а потому семантика предиката строится отталкиваясь от оси. См. [2.4 Предикаты].

Шаги адресации
[4]    Step    ::=    AxisSpecifier NodeTest Predicate*
| AbbreviatedStep
[5]    AxisSpecifier    ::=    AxisName '::'
| AbbreviatedAxisSpecifier

2.2 Оси

Можно использовать следующие оси:

  • ось child включает непосредственного потомка текущего узла контекста

  • ось descendant состоит из потомков текущего узла контекста. Потомок - это непосредственный потомок, непосредственный потомок непосредственного потомка и так далее. Таким образом, ось потомков не содержит узлы атрибутов и узлы пространств имен.

  • ось parent включает непосредственного родителя текущего узла контекста, если таковой имеется

  • ось ancestor состоит из предков текущего узла контекста. Предки текущего узла контекста - это его родитель, родитель родителя и так далее. Таким образом, ось ancestor всегда будет содержать корневой узел, за исключением единственного случая, когда корневой узел является узлом контекста.

  • ось following-sibling состоит из всех последующих узлов, которые с узлом контекста имеют общего родителя. Если узлом контекста является узел атрибута или узел пространства имен, ось following-sibling будет пустой.

  • ось preceding-sibling состоит из всех предшествующих узлов, которые с узлом контекста имеют общего родителя. Если узлом контекста является узел атрибута или узел пространства имен, ось preceding-sibling будет пустой

  • ось following. В документе, где располагается текущий узел контекста, находит все узлы, которые записанные после узла контекста. В число отобранных не попадают потомки текущего узла контекста, а также узлы атрибутов и пространств имен.

  • ось preceding. В документе, где располагается текущий узел контекста, находит все узлы, которые предшествуют узлу контекста. В число отобранных не попадают предки текущего узла контекста, а также узлы атрибутов и пространств имен.

  • ось attribute состоит из атрибутов текущего узла контекста. Если текущий узел контекста не является элементом, ось будет пустой.

  • ось namespace состоит из узлов пространства имен, относящихся к текущему узлу контекста. Если текущий узел контекста не является элементом, ось будет пустой.

  • ось self содержит только сам текущий узел контекста

  • ось descendant-or-self образуется текущим узлом контекста и его потомками

  • ось ancestor-or-self образуется текущим узлом контекста и его предками. Как результат, ось ancestor (примечание редактора: здесь, вероятно, ошибка — речь об оси ancestor-or-self — но в английском оригинале написано именно так) будет включать корневой узел.

Замечание: Оси ancestor, descendant, following, preceding и self осуществляют разбиение документа (если игнорировать узлы атрибутов и пространств имен). При этом указанные оси не пересекаются, а все вместе задействуют все узлы документа.
Оси
[6]    AxisName    ::=    'ancestor'
| 'ancestor-or-self'
| 'attribute'
| 'child'
| 'descendant'
| 'descendant-or-self'
| 'following'
| 'following-sibling'
| 'namespace'
| 'parent'
| 'preceding'
| 'preceding-sibling'
| 'self'

2.3 Проверка узлов

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

  • для оси attribute основным типом узлов является атрибут.
  • для оси namespace основным типом узлов является пространство имен.
  • для остальных осей основным типом узлов является элемент.

Правило проверки узлов, соответствующее сценарию QName, имеет результатом true тогда и только тогда, когда тип узла (см. [5 Модель данных]) совпадает с основным типом узлов, а его расширенное имя совпадает с расширенным именем, указанным этим QName. Например, child::para собирает элементы para, являющиеся непосредственными потомками текущего узла контекста. Если текущий узел контекста не имеет непосредственного потомка para, то будет получен пустой набор узлов. attribute::href в текущем узле контекста выбирает атрибут href. Если текущий узел контекста не имеет атрибута href, будет получен пустой набор узлов.

QName в правиле для проверки узла, преобразуется в расширенное имя с помощью деклараций пространств имен в контексте этого выражения. Точно так же преобразуются названия типов элементов в начальных и конечных тэгах, за исключением того, что не используется пространство имен по умолчанию, декларированное с помощью xmlns: если QName не имеет префикса, URI пространства имен будет нулевым (таким же способом обрабатываются названия атрибутов). Если QName имеет префикс, для которого в контексте выражения нет соответствующей декларации пространства имен, фиксируется ошибка.

Правило проверки узлов * имеет результатом true для любого узла, если его тип соответствует основному. Например, child::* найдет все элементы, являющиеся непосредственными потомками текущего узла контекста, а attribute::* соберет все атрибуты текущего узла контекста.

Правило проверки узлов может иметь вид NCName:*. В этом случае префикс, так же как и в случае с QName, преобразуется с помощью деклараций пространства имен в контексте. Если для этого префикса в контексте выражения не найдено соответствующей декларации пространства имен, фиксируется ошибка. Указанное правило проверки узла будет выдавать true для любого узла основного типа, чье расширенное имя имеет именно то URI пространства имен, к которому привязан указанный префикс, независимо от локальной части в названии узла.

Правило проверки узлов text() будет давать результат true для любого текстового узла. Например, child::text() будет собирать текстовые узлы, являющиеся непосредственными потомками текущего узла контекста. Точно так же, правило проверки узлов comment() будет выдавать true для любого узла комментария, а правило проверки узлов processing-instruction() - для любой инструкции обработки. Правило проверки processing-instruction() может иметь аргумент типа Literal. В этом случае проверка будет давать true для любой инструкции проверки, чье название соответствует значению этого аргумента.

Правило проверки узлов node() будет выдавать true для любого узла, к какому бы типу он не относится.
[7]    NodeTest    ::=    NameTest
| NodeType '(' ')'
| 'processing-instruction' '(' Literal ')'

2.4 Предикаты

Оси делятся на прямые и обратные. Ось, содержащая лишь текущий узел контекста или те узлы, которые в документе следуют за ним, называется прямой осью (forward axis). Ось, содержащая текущий узел контекста или те узлы, которые в документе предшествуют ему, называется обратной осью (reverse axis). Таким образом, оси ancestor, ancestor-or-self, preceding и preceding-sibling являются обратными осями, а все остальные - прямыми. Поскольку ось self всегда содержит не более одного узла, то нет разницы, является ли она прямой или обратной. Положение близости (proximity position) по отношению к оси для какого-либо члена в наборе узлов определяется как положение узла в наборе, когда последний выстроен в соответствии с порядком следования узлов в документе, если ось является прямой, или в обратном порядке, если ось является обратной. Первая позиция имеет номер 1.

Для получения нового набора предикат фильтрует имеющийся набор узлов, отталкиваясь от оси. Каждый узел в исходном наборе, подлежащем фильтрации, поочередно становится узлом контекста и для него проверяется PredicateExpr. При этом в качестве размера контекста используется количество узлов в исходном наборе, а в качестве положения в контексте берется положение близости к оси. Если для данного узла PredicateExpr оценивается как true, то этот узел попадает во вновь создаваемый набор узлов, в противном случае узел туда не попадает.

Проверка PredicateExpr сводится к обработке Expr и приведению результата к булевому значению. Если результатом обработки является число, оно будет преобразовано в true, если соответствует положению узла в контексте. В противном случае оно преобразуется в false. Если же результат обработки не является числом, то он будет приведен к булевому значению как при вызове функции boolean. Таким образом, путь адресации para[3] равнозначен para[position()=3].

Предикаты
[8]    Predicate    ::=    '[' PredicateExpr ']'
[9]    PredicateExpr    ::=    Expr

2.5 Сокращенный синтаксис

Некоторые примеры путей адресации, использующих сокращенный синтаксис:

  • para находит элемент para, являющийся непосредственным потомком текущего узла контекста

  • * находит все элементы, являющиеся непосредственными потомками текущего узла контекста

  • text() находит все текстовые узлы, являющиеся непосредственными потомками текущего узла контекста

  • @name выделяет атрибут name в текущем узле контекста

  • @* находит все атрибуты текущего узла контекста

  • para[1] находит первый непосредственный потомок para текущего узла контекста

  • para[last()] находит последний непосредственный потомок para текущего узла контекста

  • */para находит все потомки во втором поколении para текущего узла контекста

  • /doc/chapter[5]/section[2] в doc в пятом chapter находит второй section

  • chapter//para собирает элементы para, являющиеся потомками элемента chapter, который является непосредственным потомком текущего узла контекста

  • //para собирает все para, являющиеся потомками корневого узла документа, то есть находит все элементы para в том документе, где располагается текущий узел контекста

  • //olist/item в документе, где располагается текущий узел контекста, находит все элементы item, имеющие родителем olist

  • . выделяет текущий узел контекста

  • .//para собирает элементы para, являющиеся потомками текущего узла контекста

  • .. выделяет родителя текущего узла контекста

  • ../@lang выделяет атрибут lang, принадлежащий родителю текущего узла контекста

  • para[@type="warning"] находит все непосредственные потомки para текущего узла контекста, имеющие атрибут type со значением warning

  • para[@type="warning"][5] находит пятый по счету из непосредственных потомков para текущего узла контекста, имеющих атрибут type со значением warning

  • para[5][@type="warning"] извлекает пятый непосредственный потомок para текущего узла контекста, если этот потомок имеет атрибут type со значением warning

  • chapter[title="Introduction"] получает непосредственный потомок текущего узла контекста chapter, который в свою очередь имеет один или несколько непосредственных потомков title со строковым значением, равным Introduction

  • chapter[title] находит непосредственный потомок chapter текущего узла контекста, который имеет один или несколько непосредственных потомков title

  • employee[@secretary and @assistant] находит все непосредственные потомки employee данного узла контекста, которые имеют оба атрибута secretary и assistant

Самой важной является аббревиатура child::, которую при записи шага адресации всегда можно опустить. Фактически, child используется как ось по умолчанию. Например, путь адресации div/para становится сокращением для child::div/child::para.

Аналогичные аббревиатуры имеются и для атрибутов: attribute:: может быть сокращен до @. Например, путь адресации para[@type="warning"] является сокращением для child::para[attribute::type="warning"], а следовательно, находит непосредственные потомки para, имеющие атрибут type, значение которого равно warning.

// является сокращением для /descendant-or-self::node()/. Например, //para - это сокращение для /descendant-or-self::node()/child::para, а потому будет находить в документе все элементы para (путь //para найдет элемент para, даже если последний является элементом документа, поскольку узел элемента документа является непосредственным потомком корневого узла). div//para - это сокращение для div/descendant-or-self::node()/child::para, а потому находит все потомки para для непосредственного потомка div.

Замечание: Путь адресации //para[1] имеет иное значение, чем путь адресации /descendant::para[1]. Последний отыскивает первый элемент-потомок para, а предыдущий находит все элементы-потомки para, являющиеся для своего родителя первым непосредственным потомком para.

Шаг адресации . является сокращением для self::node(). Особенно эта запись полезна в сочетании с //. Например, путь адресации .//para является сокращением для

self::node()/descendant-or-self::node()/child::para

а потому будет находить все элементы para, являющиеся потомками текущего узла контекста.

Точно так же, шаг адресации .. является сокращением для parent::node(). Например, ../title - это сокращенная запись для parent::node()/child::title, а потому для родителя текущего узла контекста будет находить непосредственные потомки title.

Аббревиатуры
[10]    AbbreviatedAbsoluteLocationPath    ::=    '//' RelativeLocationPath
[11]    AbbreviatedRelativeLocationPath    ::=    RelativeLocationPath '//' Step
[12]    AbbreviatedStep    ::=    '.'
| '..'
[13]    AbbreviatedAxisSpecifier    ::=    '@'?

Назад | Содержание | Вперед

 

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...