[an error occurred while processing this directive]

3 Выражения

3.1 Основы

VariableReference заменяется значением, которое в текущем контексте поставлено в соответствие данному имени переменной (согласно схеме привязки переменных контекста). Если же по схеме привязки переменных контекста с данным именем переменной не связано ни одно значение, фиксируется ошибка.

Для группировки выражений могут использоваться круглые скобки. [14]    Expr    ::=    OrExpr[15]    PrimaryExpr    ::=    VariableReference | '(' Expr ')' | Literal | Number | FunctionCall

3.2 Вызовы функций

При обработке выражения FunctionCall используется FunctionName, позволяющее функцию в выражении сопоставить с библиотекой функций, соответствующей контексту обрабатываемого выражения, обработать каждый из аргументов, приведя к тому типу, который необходим для этой функции, и наконец вызвать саму функцию, передав ей преобразованные аргументы. Если указано неправильное количество аргументов или какой-либо аргумент не может быть приведен к требуемому типу, фиксируется ошибка. Результатом обработки выражения FunctionCall будет результат, возвращаемый соответствующей функцией.

Приведение аргумента к типу string осуществляется как при вызове функции string. Приведение к типу number осуществляется как при вызове функции number. Приведение к типу boolean осуществляется как при вызове функции boolean. Аргумент, тип которого не соответствует набору узлов, уже не может быть приведен к этому типу. [16]    FunctionCall    ::=    FunctionName '(' ( Argument ( ',' Argument )* )? ')' [17]    Argument    ::=    Expr

3.3 Наборы узлов

В качестве выражения может использоваться путь адресации. Результатом обработки такого выражения будет набор узлов, отобранных согласно указанному пути адресации.

Оператор | находит объединение операндов, которые должны являться наборами узлов.

Точно так же, как и в случае с путями адресации, для фильтрации выражений могут использоваться предикаты. Однако если результатом обработки выражения, подлежащего фильтрации, будет не набор узлов, фиксируется ошибка. Указанный предикат осуществляет фильтрацию набора узлов относительно оси child.

Замечание: Значение предиката решающим образом зависит от используемой оси. Например, preceding::foo[1] возвращает первый элемент foo, встретившийся при сканировании документа в обратном порядке, поскольку предикат [1] относится к оси preceding. И наоборот, (preceding::foo)[1] возвращает первый элемент foo, обнаруженный при просмотре документа в прямом порядке, поскольку в этом случае с предикатом [1] связана ось child.

Операторы / и // формируют и выражение, и относительный путь адресации. Если результатом обработки такого выражения окажется не набор узлов, фиксируется ошибка. Оператор / образует композицию в точности так же, как символ /, использовавшийся в пути адресации. Как и в случае с путями адресации, // является сокращением для /descendant-or-self::node()/.

Не существует таких типов объектов, которые можно было бы преобразовать в набор узлов. [18]    UnionExpr    ::=    PathExpr | UnionExpr '|' PathExpr[19]    PathExpr    ::=    LocationPath | FilterExpr | FilterExpr '/' RelativeLocationPath | FilterExpr '//' RelativeLocationPath[20]    FilterExpr    ::=    PrimaryExpr | FilterExprPredicate

3.4 Булевы значения

Объект типа boolean может иметь два значения: true и false.

Обработка выражения or сводится к обработке каждого операнда и приведению его значения к булевому типу, как если бы имел место вызов функции boolean. Если значением какого-либо из операндов будет true, то и значением всего выражения в целом тоже будет true, в противном случае это будет false. Если в результате обработки левого операнда получено true, то обработка правого операнда не производится.

Обработка выражения and сводится к обработке каждого операнда и приведению его значения к булевому типу, как если бы имел место вызов функции boolean. Если значением обоих операндов будет true, то и значением всего выражения будет true, в противном случае это будет false. Если в результате обработки левого операнда получено false, то обработка правого операнда не производится.

Обработка EqualityExpr (который содержит не только RelationalExpr) или RelationalExpr (который содержит не только AdditiveExpr) сводится к сравнению объектов, полученных в результате обработки обоих операндов. Процедура сравнения объектов описывается в трех следующих параграфах. В первом параграфе сравнение наборов узлов определяется через сравнение более элементарных объектов. Это в равной степени относится к =, !=, <=, <, >= и >. Во втором параграфе описываются процедуры сравнения = и != для объектов, не являющихся наборами узлов. В третьем параграфе для объектов, не являющихся наборами узлов, описываются операторы сравнения <=, <, >= и >.

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

Если ни один из объектов, подлежащих сравнению, не является набором узлов, а оператором является = или !=, то перед сравнением эти объекты приводятся к единому типу по следующему алгоритму: Если по крайней мере один из сравниваемых объектов имеет булевый тип, то оба сравниваемых объекта приводятся к булевому типу как при вызове функции boolean. В противном случае, если хотя бы один из сравниваемых объектов является числом, то оба объекта преобразуется в число как при вызове функции number. В остальных случаях оба сравниваемых объекта преобразуются в строки как при вызове функции string. Оператор сравнения = будет иметь результатом true тогда и только тогда, когда оба объекта идентичны. Оператор сравнения != будет иметь результатом true тогда и только тогда, когда объекты неидентичны. Сравнение чисел осуществляется согласно требованиям IEEE 754 [IEEE 754]. Два булевых значения равны, если оба являются true или оба являются false. Две строки считаются равными тогда и только тогда, когда обе образованы одной и той же последовательностью UCS символов.

Замечание: Если $x соответствует набору узлов, то выражение $x="foo" имеет иное значение, чем not($x!="foo"): Первое выражение имеет результатом true тогда и только тогда, когда в $x имеется какой-нибудь узел со строковым значением foo. Второе выражение имеет результатом true когда и только тогда, когда в $x все узлы имеют строковое значение foo.

Если ни один из подлежащих сравнению объектов не является набором узлов, а оператором является <=, <, >= или >, то сравниваемые объекты сперва преобразуются в числа, а затем выполняется сравнение этих чисел в соответствии с требованиями IEEE 754. Оператор сравнения < будет давать true тогда и только тогда, когда первое число меньше второго. Оператор сравнения <= будет давать true тогда и только тогда, когда первое число меньше или равно второму. Оператор сравнения > будет давать true тогда и только тогда, когда первое число больше второго. Оператор сравнения >= будет давать true тогда и только тогда, когда первое число больше или равно второму.

Замечание: Если в XML документе встречается выражение XPath, то операторы < и <= должны быть маскированы в соответствии с правилами XML 1.0, например, заменой на &lt; и &lt;= соответственно. В следующем примере значением атрибута test является выражение XPath:
<xsl:if test="@value &lt; 10">...</xsl:if>
[21]    OrExpr    ::=    AndExpr | OrExpr 'or' AndExpr[22]    AndExpr    ::=    EqualityExpr | AndExpr 'and' EqualityExpr[23]    EqualityExpr    ::=    RelationalExpr | EqualityExpr '=' RelationalExpr | EqualityExpr '!=' RelationalExpr[24]    RelationalExpr    ::=    AdditiveExpr | RelationalExpr '<' AdditiveExpr | RelationalExpr '>' AdditiveExpr | RelationalExpr '<=' AdditiveExpr | RelationalExpr '>=' AdditiveExpr
Замечание: Согласно представленной выше грамматике, операторы будут иметь следующий порядок приоритета (наименьший приоритет идет первым): Все указанные операторы имеют ассоциативность слева. Например, выражение 3 > 2 > 1 эквивалентно выражению (3 > 2) > 1, имеющему значение false.

3.5 Числа

Число в XPath имеет представление с плавающей точкой. Число может принимать любое значение в 64-битном формате IEEE 754 двойной точности [IEEE 754]. Сюда включены специальное значение "Not-a-Number" (NaN), положительная и отрицательная бесконечности, а также положительный и отрицательный нули. Список основных правил стандарта IEEE 754 см. в главе 4.2.3 документа [JLS]

Операнды для числовых операторов преобразуются в числа как при вызове функции number.

Оператор + выполняет сложение.

Оператор - осуществляет вычитание.

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

Оператор div осуществляет деление чисел с плавающей точкой в соответствии с требованиями IEEE 754.

Оператор mod возвращает остаток от усекающего деления. Например,

Замечание: Указанный оператор аналогичен оператору % в Java или ECMAScript.
Замечание: Данный оператор отличается от оператора remainder из IEEE 754, который возвращает остаток округляющего деления.
Числовые выражения
[25]    AdditiveExpr    ::=    MultiplicativeExpr | AdditiveExpr '+' MultiplicativeExpr | AdditiveExpr '-' MultiplicativeExpr[26]    MultiplicativeExpr    ::=    UnaryExpr | MultiplicativeExprMultiplyOperatorUnaryExpr | MultiplicativeExpr 'div' UnaryExpr | MultiplicativeExpr 'mod' UnaryExpr[27]    UnaryExpr    ::=    UnionExpr | '-' UnaryExpr

3.6 Строки

Строки образуются последовательностью из нуля и более символов, определенных в Рекомендации XML [XML]. Следовательно, в XPath каждый символ соответствует единственному абстрактному символу Unicode с единственным соответствующим скалярным значением Unicode (см. [Unicode]). Это не то же самое, что 16-битное значение кода Unicode, когда абстрактный символ со скалярным значением, большим чем U+FFFF, представляется в кодировке Unicode парой 16-битных значений (суррогатной парой). Во многих языках программирования строка представляется в виде последовательности 16-битных значений кодировки Unicode. Реализация XPath с помощью таких языков должна гарантировать, что каждая суррогатная пара обрабатывается именно как один символ XPath.

Замечание: В кодировке Unicode две строки могут считаться идентичными даже несмотря на то, что они образованы различными последовательностями абстрактных символов Unicode. Например, некоторые ударные символы могут быть представлены как в собранном (precompressed), так и в разобранном (decompressed) виде. Поэтому выражения XPath могут дать неожиданный результат, если такие символы в XPath выражении и в XML документе не были нормализованы в каноническую форму. См. документ [Character Model].

3.7 Лексическая структура

В результате лексического анализа всегда возвращается самая длинная из возможных лексем.

Для большего удобства чтения в выражения могут быть вставлены пробельные символы, даже если грамматика и не содержит на то явных указаний: в шаблонах перед любым ExprToken и после него всегда можно свободно поставить ExprWhitespace.

Чтобы устранить указанную неоднозначность грамматики ExprToken, должны применяться следующие специальные правила лексического анализа:

Лексическая структура выражения
[28]    ExprToken    ::=    '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::' | NameTest | NodeType | Operator | FunctionName | AxisName | Literal | Number | VariableReference[29]    Literal    ::=    '"' [^"]* '"' | "'" [^']* "'" [30]    Number    ::=    Digits ('.' Digits?)? | '.' Digits[31]    Digits    ::=    [0-9]+ [32]    Operator    ::=    OperatorName | MultiplyOperator | '/' | '//' | '|' | '+' | '-' | '=' | '!=' | '<' | '<=' | '>' | '>=' [33]    OperatorName    ::=    'and' | 'or' | 'mod' | 'div' [34]    MultiplyOperator    ::=    '*' [35]    FunctionName    ::=    QName - NodeType[36]    VariableReference    ::=    '$' QName[37]    NameTest    ::=    '*' | NCName ':' '*' | QName[38]    NodeType    ::=    'comment' | 'text' | 'processing-instruction' | 'node' [39]    ExprWhitespace    ::=    S

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

  [an error occurred while processing this directive]