 | XPath
Семечко в сердцевине яблока незаметно в саду.
Валлийская пословица
В предыдущем разделе было показано, как использовать XPath для ссылки на элементы в примерах XML-документов. Например, для просмотра элементов дерева используются такие выражения XPath, как / (корневой документ), страница (ожидаемый тип дочернего документа) и .. (родитель узла контекста). В следующих разделах будет показано, как получить доступ к любому фрагменту XML-документа с помощью соответствующей комбинации выражений XPath.
В XPath также имеются функции множества, строковые и математические функции. Хотя они не являются необходимыми в сравнении с большинством других языков сценариев, например, с Perl или JavaScript, в отношении краткости или эффективности, в большинстве случаев можно создавать XSLT-шаблоны, в которых эти функции в сочетании с соответствующей логикой могут выполнять практически все, что возможно в других языках программирования. В данном разделе рассматриваются выражения XPath, представленные в предыдущем разделе о XSLT, и подробно представляются некоторые концепции.
Оси
Ключевой концепцией в XPath является понятие осей. В XPath ось представляет собой набор узлов, лежащих выше (элементы parent и ancestor), ниже (элементы child и descendant), слева (элементы preceding и preceding-sibling) или справа (элементы following и following-sibling) узла контекста. Оси preceding и following относятся к элементам, находящимся, соответственно, до и после узла контекста в порядке документов, тогда как оси preceding-sibling и following-sibling относятся к элементам с тем же самым родительским элементом, что и узел контекста. Ось self представляет собой собственно узел контекста, ее можно объединять с двумя другими осями для образования осей ancestor-or-self и descendant-or-self. Доступ к любой части XML-документа обеспечивается с помощью добавления к этим осям осей attribute и namespace.
Сокращенный и полный синтаксис
Некоторые оси XPath можно (но не обязательно) описать в сокращенном синтаксисе, в некоторой степени похожем на синтаксис® оболочки файловой системы UNIX. Это дочерние оси (отмечены звездочкой (*) или более наглядно - требуемым типом дочернего элемента), родительские (..), собственные оси (.), оси атрибутов (@") и оси-собственные потомки (//). Для других осей необходимо использовать полный синтаксис. Такой синтаксис будет показан в некоторых следующих примерах.
Шаги и путь положения
Шаги положения образуют основу для пути положения. В качестве разделителя шагов положения используется косая черта (/). Путь положения представляет собой последовательность сцепленных экземпляров осей, представленных ранее. Например, начиная с узла контекста путь положения может подниматься на два уровня, находить элемент, заданный предикатом, опускаться в этом поддереве до определенного элемента и возвращать один из его атрибутов:
../../page[starts-with(@label, 'A')]//page[count(ancestor::page) = 3]/@href
|
XPath-функции
 |
Заключение в кавычки значений в XPath
Обратите внимание, что в предыдущем выражении XPath использовались одинарные кавычки ('). Данное выражение скорее всего находится в теге XSLT в качестве значения некоторого атрибута. Значение атрибута, разумеется, заключается в двойные кавычки ("), использование таких кавычек во встроенных элементах, например, в выражении XPath, приведет к разрыву тега XSLT. |
|
Создавать строковые и математические операции в XSLT можно с помощью функций, предоставляемых XPath. Например, если требуется добавить значения двух переменных xsl:variable элементов x и y, то используется следующая функция:
<xsl:value-of select="$x + $y"/>
|
Данная функция возвращает число, как и многие другие XPath-функции. XPath предоставляет функции для следующих математических операций: сложение (+), вычитание (-), умножение (*), деление (div) и модуль или остаток (mod).
XPath-функции также могут возвращать логическое значение (true или false). Это важно при использовании условной логики:
<xsl:if test="$x > $y"> ... </xsl:if>
|
XPath-функции также могут возвращать строки:
<xsl:value-of select="concat($x, ' - ', $y)"/>
|
В этом случае функция concat() может допускать любое количество аргументов, больших единицы. Другая полезная строковая функция - normalize-space(string), удаляющая начальные и замыкающие пробелы и уменьшающая количество последовательных внутренних
символов пробела до одного. Далее в списке представлены другие строковые XPath-функции:
-
starts-with(string, string): Возвращает true, если первый аргумент начинается со второго, в противном случае возвращает false. Функция представлена в предыдущем примере;
-
contains(string, string): Возвращает true, если первый аргумент начинается со второго, в противном случае возвращает false;
-
substring-before(string, string): Возвращает подстроку первого аргумента, расположенную до второго аргумента;
-
substring-after(string, string): Возвращает подстроку первого аргумента, расположенную после второго аргумента;
-
substring(string, number, number?): Возвращает подстроку первого аргумента, начинающуюся с положения, указанного вторым аргументом. Длина подстроки определяется третьим аргументом. Обратите внимание, что позиции в этой функции начинаются с 1, а не с 0;
-
string-length(string?): Возвращает число, указывающее длину дополнительного аргумента. Если аргумент не передан, используется значение узла контекста;
-
translate(string, string, string): Возвращает первый аргумент с заменами символов второго аргумента с позиционным сопоставлением символов в третьем аргументе.
XPath-функции могут также возвращать множества узлов. Например, в примере sitemap.xml можно найти элементы страниц с дочерними элементами страниц:
<xsl:value-of select="count(//page[page])"/>
|
Здесь разультат набора узла включен в функцию, возвращающую число. Номер, возвращаемый XPath-функцией count(), равняется 3; это счетчик элементов страниц со значениями меток A, AA и AAA, у каждого из которых имеются дочерние элементы страниц. Обратите внимание, что в предыдущем коде использовалась ось потомков в сокращенном синтаксисе (//). Если перед символом // ничего нет, выполняется рекурсивный поиск из корневого элемента; в больших документах такой поиск может потребовать много ресурсов, поэтому необходимо следить за использованием данного символа. Заключенный в квадратные скобки ([ и ]) предикат размещается в этих элементах страницы и требует наличия у этих элементов дочерних элементов страниц. Содержимое данного предиката является выражением XPath, "страницей" на дочерней оси. Обратите внимание, что с помощью вложения другого предиката данную логику можно расширить до следующего выражения и получить количество страниц, имеющих дочерние страницы, которые также имеют дочерние страницы:
<xsl:value-of select="count(//page[page[page]])"/>
|
Как можно ожидать, результат равен 2, то есть количеству элементов страниц A и AA.
Предположим, что требуется определить уровень вложенности узла контекста в его XML-дереве (его уровень навигации для использования языка примера карты сайта). Можно снова воспользоваться функцией count(), но для другой оси:
<xsl:value-of select="count(ancestor::page)"/>
|
Для определения глубины узла контекста используется ось предков. Далее показан пример использования этой оси в шаблоне:
<xsl:template match="/">
<xsl:for-each select="//page">
Page: <xsl:value-of select="@label"/>
,level: <xsl:value-of select="count(ancestor::page)"/>
</xsl:for-each>
</xsl:template> |
Обратите внимание, что элемент xsl:for-each управляется результатом множества узла, предоставляемым результатами его атрибута select. Выводятся следующие результаты:
<?xml version="1.0" encoding="UTF-8"?>
Page: A, level: 0
Page: AA, level: 1
Page: AAA, level: 2
Page: AAAA, level: 3
Page: AAAB, level: 3
Page: AAAC, level: 3
Page: AAB, level: 2
Page: AAC, level: 2
Page: AB, level: 1
Page: AC, level: 1
Page: B, level: 0
Page: C, level: 0
|
Атрибут select="//page" возвращает множество узла, содержащее все элементы страниц в порядке документов, начиная с корневого документа. Затем элемент xsl:for-each задает узел контекста для каждого из этих элементов страниц. Если элемент xsl:for-each не будет задавать узел контекста, выражения в элементах xsl:value-of будут недействительны.
XPath: Заключение
XPath является важным для XSLT. XPath представляет собой средства выполнения строковых и математических операций, а также поиска и отслеживания входных XML-документов. XSLT был бы слепым и беззубым без XPath.
|  |