□ /*— выберет элемент, находящийся в корне документа (элемент документа);
□ ancestor::body/a— выберет все элементы а, принадлежащие всем предкам-элементам bodyконтекстного узла;
□ /ancestor::body/a— выберет все элементы а, принадлежащие всем предкам-элементам bodyкорневого узла (это будет пустое множество);
□ //ancestor::body/a— выберет все элементы а, принадлежащие всем предкам-элементам bodyкорневого узла и потомков корневого узла; иными словами, путь //ancestor::bodyвыбирает элементы body, являющиеся предками каких-либо узлов документа, шаг a— дочерние узлы этих элементов; это выражение равносильно выражению //body[node()]/a;
□ preceding::а/@b— выберет атрибуты bэлементов а, предшествующих контекстному узлу;
□ /doc/chapter— выберет элементы chapter, принадлежащие элементам doc, которые находятся в корне документа;
□ //doc/chapter— выберет элементы chapter, которые находятся в любом элементе docдокумента;
□ doc/chapter— выберет элементы chapter, которые находятся в дочерних элементах docконтекстного узла;
□ self::node()[ancestor::body[1]]— выберет множество, состоящее из контекстного узла, если во множестве его предков bodyесть первый элемент (иначе — пустое множество); это выражение равносильно выражению self::node()[ancestor::body], поскольку если ancestor::body— непустое множество, то у него будет первый элемент;
□ *[contains(name(), 'ody')]/*[contains(name(),'able')]— выберет множество элементов, в имени которых присутствует строка "able"при условии, что они принадлежат дочерним элементам контекстного узла, в имени которых присутствует строка "ody";
□ *[last()]/preceding-sibling::*[2]— выберет второй с конца дочерний элемент контекстного узла. Это выражение равносильно *[last()-2];
□ */@*— выберет все атрибуты всех дочерних элементов контекстного узла;
□ //* [local-name(.) = 'body']— выберет все элементы bodyтекущего документа вне зависимости от их пространств имен.
В языке XSLT определяется подмножество выражений языка XPath, которые называются паттернами (от англ. pattern — образец). Паттерны представляют собой упрощенные пути выборки, которые используются для определения, соответствует ли узел заданному образцу.
Чаще всего паттерны применяются в элементе xsl:templateв атрибуте match. Шаблоны такого типа будут выполняться только для тех узлов, которые удовлетворяют заданному образцу. Например, следующий шаблон будет выполняться только для элементов body, принадлежащих элементу html:
...
Кроме этого, паттерны применяются при нумерации и при определениях ключей.
Паттерны являются сильно упрощенными путями выборки. Единственные оси, которые могут использоваться в паттернах, — это child, attributeи descendant-or-self, причем ось навигации descendant-or-selfможет быть указана только в сокращенном виде оператором " //". То, что в паттернах используются только оси атрибутов и узлов-потомков, позволяет XSLT-процессорам значительно оптимизировать процесс сопоставления узла заданному образцу — ведь теперь даже в самом худшем сценарии не нужно метаться по всему документу, выбирая узлы, содержащиеся в тех или иных осях навигации. Правда, оператор " //" остается не менее опасным — при его проверке может понадобиться перебрать всех предков текущего узла, что может быть весьма и весьма затруднительно (хотя и проще, чем перебор всех потомков).
Хоть паттерны и выглядят как пути выборки, на самом деле механизм их работы несколько иной. Они не выбирают множество узлов, как таковое, они проверяют узлы на соответствие образцу, который они определяют. Это в принципе эквивалентно выбору множества и проверке узла на вхождение в него, но, как правило, так не делается, поскольку такая проверка потребовала бы слишком больших затрат времени. Гораздо дешевле в этом смысле воспользоваться тем фактом, что синтаксис паттернов упрощен, и осей не так много для того, чтобы создать более эффективный алгоритм проверки соответствия узлов. Например, для того чтобы проверить соответствие некоторого узла, назовем его X, паттерну body/a, совершенно необязательно вычислять путь выборки body/aи затем проверять, входит ли узел Xв полученное множество. Достаточно проверить, является ли именем узла " a", а именем его родителя (если он, конечно, есть) — " body".
Читать дальше