W3C

Язык XML Path (XPath)
версия 1.0

Рекомендация W3C от 16 ноября 1999 года

Данный документ представляет собой перевод спецификации XML Path Language (XPath) Version 1.0 (W3C Recommendation) на русский язык. При этом нормативным документом считается оригинальная спецификация на английском языке, которую можно найти по адресу http://www.w3.org/TR/1999/REC-xpath-19991116. Перевод выполнен Радиком Усмановым
Представленный документ может содержать ошибки перевода.
Данная версия:
http://www.w3.org/TR/1999/REC-xpath-19991116
(доступна в форматах XML и HTML)
Последняя версия:
http://www.w3.org/TR/xpath
Предыдущие версии:
http://www.w3.org/TR/1999/PR-xpath-19991008
http://www.w3.org/1999/08/WD-xpath-19990813
http://www.w3.org/1999/07/WD-xpath-19990709
http://www.w3.org/TR/1999/WD-xslt-19990421
Редакторы:
James Clark <jjc@jclark.com>
Steve DeRose (Inso Corp. и Brown University) <Steven_DeRose@Brown.edu>

Аннотация

XPath - это язык адресации частей XML документа, предназначенный для использования с XSLT и Xpointer.

Статус этого документа

Данный документ был рассмотрен членами W3C и другими заинтересованными сторонами и утвержден Директором в качестве Рекомендации W3C. Данный документ является окончательным и может быть использован для ссылок и цитирования в других материалах в качестве нормативного документа. Участие организации W3C в разработке данной Рекомендации заключается в привлечении внимания к представленной спецификации и содействии ее широкому распространению. Результатом этой деятельности является повышение функциональности и универсальности Сети.

Перечень ошибок, выявленных в данной спецификации, доступен по адресу http://www.w3.org/1999/11/REC-xpath-19991116-errata.

Комментарии к этой спецификации можно отправлять по адресу www-xpath-comments@w3.org, доступен архив комментариев.

Несмотря на то, что нормативную силу имеет только английская версия данной спецификации, по адресу http://www.w3.org/Style/XSL/translations.html можно обнаружить ее перевод на другие языки.

По адресу http://www.w3.org/TR можно найти перечень текущих Рекомендаций W3C и другие технические материалы.

Данная спецификация является совместным результатом деятельности рабочих групп XSL и XML Linking, а потому является частью сразу двух проектов W3C Style activity и W3C XML activity.

Содержание

1 Введение
2 Пути адресации
    2.1 Шаги адресации
    2.2 Оси
    2.3 Проверка узлов
    2.4 Предикаты
    2.5 Сокращенный синтаксис
3 Выражения
    3.1 Основы
    3.2 Вызовы функций
    3.3 Наборы узлов
    3.4 Булевы значения
    3.5 Числа
    3.6 Строки
    3.7 Лексическая структура
4 Основная библиотека функций
    4.1 Функции обработки набора узлов
    4.2 Функции обработки строк
    4.3 Функции обработки булевых значений
    4.4 Функции обработки чисел
5 Модель данных
    5.1 Корневой узел
    5.2 Узлы элементов
        5.2.1 Уникальные ID
    5.3 Узлы атрибутов
    5.4 Узлы пространства имен
    5.5 Узлы инструкций обработки
    5.6 Узлы комментариев
    5.7 Текстовые узлы
6 Соответствие

Приложения

A Ссылки
    A.1 Нормативные ссылки
    A.2 Остальные ссылки
B Составление информационного набора XML (Обсуждение спецификации)
C Словарь (Обсуждение спецификации)

1 Введение

Язык XPath является результатом попыток создать единые синтаксис и семантику для функционала, совместно используемого XSL Transformations [XSLT] и XPointer [XPointer]. Главная задача языка XPath - адресация частей в XML документе [XML]. Для достижения этой цели язык дополнительно наделен основными функциями для манипулирования строками, числами и булевыми значениями. В XPath используется компактный синтаксис, отличный от принятого в XML, облегчающий использование языка XPath при записи адресов URI и значений атрибутов XML. XPath работает не с внешним синтаксисом XML документа, а с его абстрактной логической структурой. XPath получил такое название потому, что использовался в URL для записи путей, обеспечивающих навигацию по иерархической структуре XML документа.

Язык XPath спроектирован так, что помимо поддержки адресации он обладает естественным набором элементов, которые могут использоваться для сравнения (проверки, соответствует ли узел некому шаблону). Такой порядок использования языка XPath описывается в спецификации XSLT.

XPath представляет XML документ в виде дерева узлов. Узлы бывают различных типов, например, узлы элементов, узлы атрибутов и узлы текста. Для каждого типа узлов в XPath определяется способ вычисления строкового значения. Некоторые типы узлов имеют также имя. XPath полностью поддерживает пространства имен XML [XML Names]. В результате, имя любого узла в этом языке образуется из двух частей: локальной части и URI некого пространства имен (возможно, нулевого), такая комбинация называется расширенным именем. Указанная модель данных подробно описана в главе [5 Модель данных].

Главной синтаксической конструкцией языка XPath является выражение. Любое выражение соответствует сценарию Expr. В результате обработки выражения получается объект, относящийся к одному из четырех основных типов:

Обработка выражений осуществляется, отталкиваясь от некого контекста. В спецификациях XSLT и XPointer указывается, каким образом в XSLT и XPointer, соответственно, определяется контекст для выражений XPath. Контекст образуется из:

Положение в контексте всегда меньше или равно размеру контекста.

Схема привязки переменных контекста образуется в результате отображения множества имен переменных на множество значений переменных. Значением переменной является объект, относящийся к одному из типов, допустимых для значений выражений, либо к какому-либо дополнительному типу, не описанному в спецификации.

Библиотека функций образуется в результате отображения множества названий функций на множество функций. Каждая функция имеет нуль или более аргументов и возвращает один результат. В данном документе описывается основная библиотека функций, которую должны поддерживать все реализации XPath (см. [4 Основная библиотека функций]). Для любой функции в основной библиотеке и аргументы, и результат выполнения относятся к четырем основным типам. И XSLT, и XPointer дополняют XPath, определяя дополнительные функции, часть новых функций оперирует с четырьмя основными типами, остальные - дополнительными типами данных, определенными в XSLT и XPointer.

Декларации пространства имен образуются в результате отображения множества префиксов на множество идентификаторов URI пространств имен.

Привязка переменных контекста, библиотека функций и декларации пространства имен используются для обработки отдельных частей выражения и остаются неизменными на протяжении обработки всего выражения. Узел контекста, размер контекста и положение в контексте, используемые для обработки частей выражения, иногда могут отличаться от используемых для обработки выражения в целом. Некоторые типы выражений меняют текущий узел контекста, однако размер контекста и положение в контексте могут менять только предикаты (см. [2.4 Предикаты]). Если описывается обработка некоторого типа выражений, то всегда явно указывается, когда для обработки частей выражения используется другой узел контекста, измененные размер контекста или положение в контексте. Если же об узле контекста, размере контекста или положении в контексте в описании ничего не сказано, считается, что они остаются неизменными в ходе обработки всех подвыражений в выражении указанного типа.

Выражения XPath часто используются в атрибутах XML. Описываемая в этой главе грамматика примеряется к значению атрибута после выполнения нормализации, описанной в XML 1.0. Так, если, к примеру, в грамматике используется символ <, то в исходном XML документе его нельзя записывать просто как <. Вместо этого, согласно правилам XML 1.0, его необходимо маскировать, например, записав как &lt;. Строковые значения, используемые в выражениях, заключаются в одинарные или двойные кавычки, которые используются также для записи атрибутов XML. Поэтому, чтобы символ кавычки в этом выражении не интерпретировался XML процессором как конец значения атрибута, его необходимо записывать как ссылку на символ (&quot; или &apos;). Впрочем, если атрибут XML был заключен в двойные кавычки, в выражении можно свободно использовать символы одинарных кавычек, и наоборот.

Другим важным типом выражений является путь адресации (location path). Путь адресации выбирает некое множество узлов, отталкиваясь от некоторого узла контекста. Результатом обработки выражения, соответствующего пути адресации, является множество узлов, собранных согласно этому пути. Путь адресации может рекурсивно содержать выражения, используемые для фильтрации наборов узлов. Путь адресации соответствует сценарию LocationPath.

В представленной далее грамматике используются незавершенные конструктивы QName и NCName, описанные в [XML Names], а также пробельный символ S, описанный в [XML]. Грамматика использует ту же самую нотацию EBNF, что [XML] (за исключением того, что названия грамматических конструкций всегда пишутся с заглавной буквы).

Обработка выражения начинается с его разбиения на строки символов, подлежащих преобразованию в лексемы. Затем идет разбор полученной последовательности лексем. В промежутки между лексемами могут свободно ставиться пробельные символы. Процесс преобразования в лексемы (tokenization) описан в главе [3.7 Лексическая структура].

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

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

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

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

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

Относительный путь адресации состоит из последовательности одного или нескольких шагов адресации, отделенных друг от друга символом /. Шаги в относительном пути адресации считаются слева направо. На каждом шаге осуществляется отбор узлов, отталкиваясь от некоторого узла контекста. Основная последовательность шагов образуется последовательным перечислением шагов в порядке их выполнения. Сперва, отталкиваясь от узла контекста, последовательность шагов набирает некий набор узлов. Затем каждый узел в этом наборе поочередно используется как узел контекста для следующего шага. Все наборы узлов, полученных после выполнения такого шага, опять собираются вместе. В итоге в полученном объединении будет собран набор узлов, идентифицируемых данной последовательностью шагов. Например, формула 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) состоят из трех частей:

Синтаксис шага адресации образуется из названия оси и правила проверки узлов, отделенных друг от друга двумя символами двоеточия. За ними следует нуль или более выражений, каждое из которых заключено в квадратные скобки. Например, в выражении 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 Оси

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

Замечание: Оси 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). Если ось может содержать элементы, то для такой оси основным типом узлов будут элементы. В противном случае в качестве основного берется тип тех узлов, которые эта ось может содержать. Таким образом,

Правило проверки узлов, соответствующее сценарию 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 Сокращенный синтаксис

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

Самой важной является аббревиатура 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    ::=    '@'?

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
| FilterExpr Predicate

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
| MultiplicativeExpr MultiplyOperator UnaryExpr
| 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

4 Основная библиотека функций

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

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

4.1 Функции обработки набора узлов

Функция: number last()

Функция last возвращает число, равное размеру контекста обрабатываемого выражения.

Функция: number position()

Функция position возвращает число, равное положению в контексте обрабатываемого выражения.

Функция: number count(node-set)

Функция count возвращает количество узлов в наборе, представленном в качестве аргумента.

Функция: node-set id(object)

Функция id находит элементы по их уникальному идентификатору (см. [5.2.1 Уникальные ID]). Если аргументом функции id является набор узлов, то ее результатом будет объединение узлов, полученных в результате вызова функции id для строкового значения каждого узла в наборе, указанном в качестве аргумента. Если аргумент функции id относится к какому-либо другому типу, то этот аргумент сперва преобразуется в строку как при вызове функции string. Затем полученная строка разбивается на лексемы, разделенные пробельными символами (пробельный символ - это любая последовательность символов, соответствующих сценарию S). Результатом вызова функции в этом случае является набор узлов, состоящий из элементов, относящихся к тому же документу, где находился узел контекста, и имеющих уникальный идентификатор, равный одной из лексем, представленных в этом списке.

Функция: string local-name(node-set?)

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

Функция: string namespace-uri(node-set?)

В наборе, указанном в аргументе, функция namespace-uri находит тот узел, который в документе встретится первым, и в его расширенном имени выделяет URI пространства имен. Если указанный в аргументе набор узлов пуст, первый найденный узел не имеет расширенного имени, или же URI пространства имен в расширенном имени оказался нулевым, то функция возвращает пустую строку. Если аргумент отсутствует, то по умолчанию берется набор, в котором узел контекста является единственным членом.

Замечание: Для узлов, которые не соответствуют ни элементам, ни атрибутам, функция namespace-uri возвращает пустую строку.

Функция: string name(node-set?)

В наборе, указанном в аргументе, функция name находит узел, который в документе встретится первым, и возвращает строку, содержащую QName, которое представляет расширенное имя данного узла. Указанная конструкция QName должна представлять расширенное имя, исходя из деклараций пространств имен, доступная для того узла, чье расширенное имя должно быть представлено. Как правило, это тот самый QName, который был представлен в исходном документе XML. Однако это не обязательно должно быть так в случае, когда декларации, воздействующие на данный узел, с одним и тем же пространством имен связывают несколько префиксов. Тем не менее, реализация может содержать сведения о первоначальном префиксе представляемых узлов, в таком случае может выполняться проверка с тем, чтобы возвращаемая строка была всегда такой же, как QName, используемый в исходном документе XML. Если указанный в аргументе набор узлов пуст или первый узел не имеет расширенного имени, возвращается пустая строка. Если аргумент опущен, то по умолчанию используется набор, содержащий только узел контекста.

Замечание: Для узлов, не являющихся ни элементом, ни атрибутом, строка, возвращаемая функцией name, будет той же самой, что и строка, возвращаемая функцией local-name.

4.2 Функции обработки строк

Функция: string string(object?)

Функция string преобразует объект в строку следующим образом:

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

Замечание: Функция string не предназначена для преобразования чисел в строки для показа пользователю. Для этой цели предназначены функция format-number и элемент xsl:number из [XSLT].

Функция: string concat(string, string, string*)

Функция concat возвращает объединение представленных аргументов.

Функция: boolean starts-with(string, string)

Функция starts-with возвращает true если строка второго аргумента совпадает с началом строки первого аргумента. В противном случае функция возвращает false.

Функция: boolean contains(string, string)

Функция contains возвращает true если строка второго аргумента является частью строки первого аргумента. В противном случае функция возвращает false.

Функция: string substring-before(string, string)

Функция substring-before возвращает ту часть строки первого аргумента, которая предшествует первому появлению строки второго аргумента. Если строка второго аргумента не содержится в строке первого аргумента, то функция возвращает пустую строку. Например, substring-before("1999/04/01","/") возвратит 1999.

Функция: string substring-after(string, string)

Функция substring-after возвращает ту часть строки первого аргумента, которая следует за первым появлением строки второго аргумента. Если строка второго аргумента не содержится в строке первого аргумента, функция возвращает пустую строку. Например, substring-after("1999/04/01","/") возвращает 04/01, а substring-after("1999/04/01","19") возвращает 99/04/01.

Функция: string substring(string, number, number?)

Функция substring возвращает ту часть строки первого аргумента, которая начинается с позиции, указанной вторым аргументом, и имеет длину, указанную в третьем аргументе. Например, substring("12345",2,3) возвращает "234". Если третий аргумент не был представлен, функция возвращает подстроку, начинающуюся с позиции, указанной во втором аргументе, и продолжащуюся до конца строки. Например, substring("12345",2) возвращает "2345".

Точнее выражаясь, каждый символ в строке (см. [3.6 Строки]) имеет номер позиции: позиция первого символа - 1, второго символа - 2 и т.д.

Замечание: Такой порядок отличается от принятого в Java и ECMAScript, где метод String.substring считает позицию первого символа нулевой.

Возвращаемая подстрока содержит те символы, позиция которых больше или равна округленному значению второго аргумента, а также, если был указан третий аргумент, меньше чем сумма округленных значений второго и третьего аргументов. Использовавшиеся выше операции сравнения и сложения отвечают правилам стандарта IEEE 754, округление осуществляется как при вызове функции round. Приведенные далее примеры иллюстрируют различные нестандартные ситуации:

Функция: number string-length(string?)

Функция string-length возвращает число символов в строке (см. [3.6 Строки]). Если аргумент опущен, то по умолчанию берется узел контекста и преобразуется в строку, иными словами, берется строковое значение текущего узла контекста.

Функция: string normalize-space(string?)

Функция normalize-space возвращает строку аргумента с нормализацией пробельных символов. Сюда входит удаление начальных и завершающих пробельных символов, а также замена оставшихся последовательностей пробельных символов одиночными пробелами. Пробельными считаются символы, являющиеся таковыми согласно сценарию S в языке XML. Если аргумент опущен, то по умолчанию в строку преобразуется узел контекста, иными словами, в качестве аргумента берется строковое значение текущего узла контекста.

Функция: string translate(string, string, string)

Функция translate возвращает строку первого аргумента, в которой символы, указанные в строке второго аргумента, заменены символами строки третьего аргумента в соответствующей позиции. Например, translate("bar","abc","ABC") возвращает строку BAr. Если в строке второго аргумента имеется символ, для которого нет парного символа в соответствующей позиции третьей строки (поскольку строка второго аргумента длиннее строки третьего аргумента), то все экземпляры этого символа изымаются из первой строки. Например, translate("--aaa--","abc-","ABC") возвращает "AAA". Если какой-либо символ встретился во второй строке несколько раз, то правило замены определяется первым встреченным экземпляром. Если строка третьего аргумента длиннее, чем строка второго, лишние символы игнорируются.

Замена: Функция translate не может обеспечить преобразование регистра для всех языков. Для преобразования регистра в будущих версии XPath могут появиться дополнительные функции.

4.3 Функции обработки булевых значений

Функция: boolean boolean(object)

Функция boolean преобразует аргумент в булево значение следующим образом:

Функция: boolean not(boolean)

Функция not возвращает true тогда и только тогда, когда ее аргументом является false, и false в противном случае.

Функция: boolean true()

Функция true возвращает true.

Функция: boolean false()

Функция false возвращает false.

Функция: boolean lang(string)

Функция lang возвращает true или false в зависимости от того, является ли язык узла контекста, указываемый в атрибутах xml:lang, тем же самым языком (или подмножеством языка), что указан в строке атрибута. Язык узла контекста задается значением атрибута xml:lang, указанного в этом узле, либо, если сам узел контекста не имеет атрибута xml:lang, то значением атрибута xml:lang у его ближайшего предка, имеющего такой атрибут. Если требуемый атрибут не найден, функция lang возвращает false. Если же атрибут найден, то функция lang возвращает true когда значение этого атрибута равно значению аргумента. При этом регистр игнорируется. Кроме того, если значение атрибута имеет суффикс, начинающийся с дефиса (-), то перед сравнением такой суффикс может быть отброшен. Например, вызов функции lang("en") возвращает true если узлом контекста является любой из пяти указанных элементов:

<para xml:lang="en"/>
<div xml:lang="en"><para/></div>
<para xml:lang="EN"/>
<para xml:lang="en-us"/>

4.4 Функции обработки чисел

Функция: number number(object?)

Функция number преобразует свой аргумент в число следующим образом:

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

Замечание: Функция number не должна использоваться для преобразования числовых данных, встреченных в каком-либо элементе XML документа, если не известно, что элемент данного типа представляет числовые данные в независимом от языка формате (обычно перед показом пользователю такой элемент переводятся в формат, соответствующий языку). Кроме того, функция number не может использоваться, если независимый от языка формат элемента не соответствует синтаксису XPath для Number.

Функция: number sum(node-set)

Функция sum возвращает сумму всех узлов из набора, указанного в аргументе. Перед суммированием строковые значения узлов преобразуются в числа.

Функция: number floor(number)

Функция floor возвращает наибольшее число (ближайшее к положительной бесконечности), которое не превышает значение представленного аргумента и является целым.

Функция: number ceiling(number)

Функция ceiling возвращает наименьшее число (ближайшее в отрицательной бесконечности), которое не меньше значения представленного аргумента и является целым.

Функция: number round(number)

Функция round возвращает целое число, ближайшее к значению аргумента. Если таких чисел два, то возвращается то из них, которое ближе к положительной бесконечности. Если аргументом является NaN, функция возвращает NaN. Если аргументом является положительная бесконечность, возвращается положительная бесконечность. Если аргументом является отрицательная бесконечность, возвращается отрицательная бесконечность. Если аргументом является положительный нуль, функция возвращает положительный нуль. Если аргументом является отрицательный нуль, функция возвращает отрицательный нуль. Если аргумент меньше нуля, но больше или равен -0.5, возвращается отрицательный нуль.

Замечание: В последних двух случаях вызов функции round имеет иной результат, чем добавление 0.5 и последующий вызов функции floor.

5 Модель данных

XPath обрабатывает XML документ как древовидную структуру. В этой главе описывается, как именно XPath моделирует дерево XML документа. Указанная модель носит лишь концептуальный характер и не содержит указаний для какой-либо конкретной реализации. Взаимосвязь этой модели с XML Information Set [XML Infoset] описывается в Приложении [B XML Information Set Mapping].

XML документы, обрабатываемые XPath, должны отвечать требованиям Рекомендации XML Namespaces [XML Names].

Дерево состоит из узлов. Узлы бывают семи типов:

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

Замечание: Для узлов элементов и корневых узлов строковое значение узла - это не та же самая строка, которую возвращает метод nodeValue модели DOM (см. [DOM]).

Некоторые типы узлов имеют также расширенное имя, состоящее из двух частей: локальной части и URI пространства имен. Локальная часть - это строка, URI пространства имен - строка или null. В качестве URI пространства имен, указываемого в XML документе, может выступать ссылка URI, описанная в [RFC2396]. Это означает, что он может иметь идентификатор фрагмента и быть относительным. В процессе обработки пространства имен относительный URI должен преобразовываться в абсолютный - URI пространства имен для расширенного имени узла в модели данных всегда должен стать абсолютным. Два расширенных имени считаются идентичными, если они имеют одинаковую локальную часть и либо оба имеют нулевой URI пространства имен, либо имеют одинаковые ненулевые URI пространства имен.

Для всех узлов в документе определяется порядок, называемый порядком появления в документе. Он соответствует появлению узлов в XML представлении документа после расшифровки всех общих сущностей - точнее выражаясь, не самих узлов, а первых символов из XML представления соответствующего узла. Следовательно, корневой узел всегда будет первым узлом, а узлы элементов будут предшествовать своим непосредственным потомкам. Таким образом, порядок появления в документе упорядочивает узлы элементов согласно очередности появления в XML документе соответствующих открывающих тэгов (после подстановки всех сущностей). Считается, что в элементе узлы атрибутов и пространств имен всегда предшествуют непосредственным потомкам элемента. При этом узлы пространств имен предшествуют узлам атрибутов. Относительный порядок следования узлов пространства имен и относительный порядок следования узлов атрибутов зависят от реализации. Обратный порядок появления в документе - это порядок, обратный порядку появления в документе.

Корневые узлы и узлы элементов имеют упорядоченный список узлов непосредственных потомков. Узлы не могут иметь совместных непосредственных потомков: если один узел отличается от другого, то ни один узел непосредственного потомка первого узла не может совпасть с каким-либо узлом непосредственного потомка другого узла. Каждый узел, за исключением корневого, имеет ровно одного родителя, который является либо узлом элемента, либо корневым узлом. Корневой узел и узел элемента являются родителями для каждого из своих непосредственных потомков. Потомки узла - это непосредственные потомки данного узла и все потомки непосредственных потомков этого узла.

5.1 Корневой узел

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

Строковое значение корневого узла является объединением строковых значений всех текстовых узлов, являющихся потомками корневого узла, выстроенными согласно порядку появления в документе.

Корневой узел не имеет расширенного имени.

5.2 Узлы элементов

Для каждого элемента в документе создается узел элемента. Узел элемента имеет расширенное имя, получаемое при обработке QName этого элемента, которое, согласно рекомендации XML Namespaces [XML Names], указывается в соответствующем теге. Если QName не имеет префикса и нет пространства имен, используемого по умолчанию, то URI пространства имен для расширенного имени данного элемента будет нулевым.

Замечание: Согласно нотации в Приложении A.3 документа [XML Names], локальная часть расширенного имени соответствует атрибуту type в элементе ExpEType. URI пространства имен для расширенного имени соответствует атрибуту ns в элементе ExpEType и становится нулевым, если такой атрибут не был представлен.

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

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

5.2.1 Уникальные ID

Узел элемента может иметь уникальный идентификатор (ID). Значение этого атрибута декларируется в DTD как тип ID. Никакие два элемента в пределах одного документа не могут иметь одинаковые уникальные идентификаторы. Если XML процессор сообщает о существовании в документе двух элементов, имеющих один и тот же уникальный идентификатор (а такое возможно только если этот документ недействителен), то из двух данных элементов тот, который встретился в документе позже, будет обрабатываться как не имеющий уникального идентификатора.

Замечание: Если документ не имеет DTD, то ни один из его элементов не будет иметь уникального идентификатора.

5.3 Узлы атрибутов

С каждым узлом элемента связан набор узлов атрибутов. При этом, хотя сам элемент является родителем каждого из этих узлов атрибутов, узел атрибута непосредственным потомком своего родительского элемента не является.

Замечание: В этом заключается отличие от модели DOM, где элемент, владеющий атрибутом, родителем этого атрибута не считается (см. [DOM]).

Элементы не могут совместно использовать узлы атрибутов: Если один узел элемента отличается от другого, то ни один из узлов атрибутов, относящихся к первому узлу элемента, не может совпасть ни с одним узлом атрибута, относящимся ко второму узлу элемента.

Замечание: Оператор = проверяет, имеют ли два узла одно и то же значение, однако не проверяет, являются ли они одним и тем же узлом. Таким образом, атрибуты двух различных элементов можно сравнивать с помощью оператора =, даже несмотря на то, что они представлены различными узлами.

Атрибут, подставляемый по умолчанию, обрабатывается точно так же, как атрибут, указанный явно. Если для данного типа элемента в DTD атрибут был декларирован со значением по умолчанию #IMPLIED, однако в элементе этот атрибут представлен не был, считается, что в наборе атрибутов указанного элемента нет узла для этого атрибута.

Некоторые атрибуты, такие как xml:lang и xml:space, имеют семантику, которая распространяется на все элементы, являющиеся потомками элемента с этим атрибутом (если затем семантика не была переопределена таким же атрибутом в другом элементе, являющемся его потомком). Однако это не накладывает ограничений на местоположение узлов атрибутов в дереве документа: любой элемент имеет узлы только тех атрибутов, которые либо были явно указаны в начальном тэге или тэге пустого элемента, относящихся в этому элементу, либо были явно декларированы в DTD со значением по умолчанию.

Узел атрибута имеет расширенное имя и строковое значение. Расширенное имя получается при обработке QName, указанного в соответствующем тэге XML документа согласно Рекомендации XML Namespaces [XML Names]. Если QName атрибута не имеет префикса, URI пространства имен для имени атрибута будет нулевым.

Замечание: Согласно нотации в Приложении A.3 документа [XML Names], локальная часть расширенного имени соответствует атрибуту name элемента ExpAName, URI пространства имен расширенного имени соответствует атрибуту ns элемента ExpAName и будет нулевым, если атрибут ns в элементе ExpAName опущен.

Узел атрибута имеет строковое значение. Строковое значение нормализовано в соответствии с Рекомендацией XML [XML]. Не предусмотрено специальной обработки для атрибута, чье нормализованное значение становится строкой нулевой длины - результатом будет узел атрибута, чьим строковым значением становится строка нулевой длины.

Замечание: во внешнем DTD или внешней сущности параметра могут декларироваться атрибуты по умолчанию. Согласно рекомендации XML, если процессор XML не является проверяющим, он не обязан читать внешние DTD и внешние параметры. Соответственно, с некоторыми непроверяющими XML процессорами могут не работать стили и другой функционал, предполагающий, что дерево XPath содержит значения атрибутов по умолчанию, декларированные во внешнем DTD или сущности параметра.

Для атрибутов, декларирующих пространства имен, соответствующих узлов атрибутов не предусмотрено (см. [XML Names]).

5.4 Узлы пространства имен

С каждым элементом связан набор узлов пространства имен: по одному на каждый новый префикс пространства имен, появившийся в области видимости этого элемента, (включая и перфикс xml, явным образом декларированный Рекомендацией XML Namespaces [XML Names]), и еще один узел для пространства имен по умолчанию, если таковое имеется в области видимости элемента. Данный элемент является родителем каждого такого узла пространства имен, однако узел пространства имен непосредственным потомком соответствующего элемента родителя не становится. Элементы не могут совместно использовать узлы пространства имен: если один узел элемента отличается от другого узла элемента, то ни один из узлов пространства имен, принадлежащих одному элементу, не может совпасть с узлом пространства имен, относящихся ко второму узлу элемента. Это означает, что элемент получит узел пространства имен:

Узел пространства имен имеет расширенное имя, локальная часть которого является префиксом пространства имен (она является пустой, если данный узел относится к пространству имен по умолчанию), а идентификатор URI пространства имен всегда нулевой.

Строковое значение узла пространства имен - это URI пространства имен, связанного с данным префиксом пространства имен. Если данный URI окажется относительным, он должен обрабатываться точно так же, как URI пространства имен в расширенном имени.

5.5 Узлы инструкций обработки

Для каждой инструкции обработки создается соответствующий узел. Исключение составляют инструкции обработки, помещенные в декларацию типа документа.

Инструкция обработки имеет расширенное имя, в котором локальная часть - это адресат инструкции обработки, а URI пространства имен является нулевым. Строковое значение узла инструкции обработки - это та часть инструкции обработки, которая следует за адресатом и возможным пробельным символом. В состав строкового значения также не попадает завершающая комбинация ?>.

Замечание: Декларация XML инструкцией обработки не является. Соответственно, ни один из узлов инструкции обработки не может соответствовать декларации XML.

5.6 Узлы комментариев

Для каждого комментария создается соответствующий узел. Исключение составляют комментарии, расположенные в декларации типа документа.

Строковым значением комментария является содержимое этого комментария за исключением открывающей <!-- и закрывающей --> комбинаций.

Узлы комментария расширенного имени не имеют.

5.7 Текстовые узлы

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

Все символы в секции CDATA обрабатываются как символьные данные. Таким образом, запись <![CDATA[<]]> в исходном документе будет обрабатываться так же, как и &lt;. Оба варианта будут иметь результатом один символ < в текстовом узле дерева документа. Таким образом, секция CDATA обрабатывается так, словно были удалены комбинации <![CDATA[ и ]]>, а все символы < и & были заменены на &lt; и &amp; соответственно.

Замечание: Если текстовый узел, содержащий символ <, записывается как XML, сам символ < должен маскироваться, например, с помощью &lt; или помещением в секцию CDATA.

Символьные данные в комментариях, инструкциях обработки и значениях атрибутов текстовых узлов не образуют. Концы строк во внешних сущностях нормализуются в #xA в соответствии с Рекомендацией XML [XML].

Текстовый узел расширенного имени не имеет.

6 Соответствие

XPath изначально создавался как компонент для использования в других спецификациях. Поэтому XPath обращается к использующим его спецификациям (таким как [XPointer] или [XSLT]) за получением критериев проверки реализаций XPath, вместо того чтобы самому формулировать критерии оценки независимых реализаций XPath.


A Ссылки

A.1 Нормативные ссылки

IEEE 754
Institute of Electrical and Electronics Engineers. IEEE Standard for Binary Floating-Point Arithmetic. ANSI/IEEE Std 754-1985.
RFC2396
T. Berners-Lee, R. Fielding, and L. Masinter. Uniform Resource Identifiers (URI): Generic Syntax. IETF RFC 2396. См. http://www.ietf.org/rfc/rfc2396.txt.
XML
World Wide Web Consortium. Extensible Markup Language (XML) 1.0. W3C Recommendation. См. http://www.w3.org/TR/1998/REC-xml-19980210
XML Names
World Wide Web Consortium. Namespaces in XML. W3C Recommendation. См. http://www.w3.org/TR/REC-xml-names

A.2 Остальные ссылки

Character Model
World Wide Web Consortium. Character Model for the World Wide Web. Рабочий проект W3C. См. http://www.w3.org/TR/WD-charmod
DOM
World Wide Web Consortium. Document Object Model (DOM) Level 1 Specification. Рекомендация W3C. См. http://www.w3.org/TR/REC-DOM-Level-1
JLS
J. Gosling, B. Joy, and G. Steele. The Java Language Specification. См. http://java.sun.com/docs/books/jls/index.html.
ISO/IEC 10646
ISO (International Organization for Standardization). ISO/IEC 10646-1:1993, Information technology -- Universal Multiple-Octet Coded Character Set (UCS) -- Part 1: Architecture and Basic Multilingual Plane. Международный стандарт. См. http://www.iso.ch/cate/d18741.html.
TEI
C.M. Sperberg-McQueen, L. Burnard Guidelines for Electronic Text Encoding and Interchange. См. http://etext.virginia.edu/TEI.html.
Unicode
Unicode Consortium. The Unicode Standard. См. http://www.unicode.org/unicode/standard/standard.html.
XML Infoset
World Wide Web Consortium. XML Information Set. Рабочий проект W3C. См. http://www.w3.org/TR/xml-infoset
XPointer
World Wide Web Consortium. XML Pointer Language (XPointer). Рабочий проект W3C. См. http://www.w3.org/TR/WD-xptr
XQL
J. Robie, J. Lapp, D. Schach. XML Query Language (XQL). См. http://www.w3.org/TandS/QL/QL98/pp/xql.html
XSLT
World Wide Web Consortium. XSL Transformations (XSLT). Рекомендация W3C. См. http://www.w3.org/TR/xslt

B Отображение XML Information Set (Обсуждение спецификации)

Узлы модели данных XPath могут быть получены из информационных элементов в XML Information Set [XML Infoset] следующим образом:

Замечание: Следующая версия рабочего проекта XML Information Set, которая сменит версию от 17 мая, была близка к завершению в то время, когда была завершена подготовка текущей версии XPath. Предполагалось, что она будет реализована одновременно или чуть позже данной версии XPath. Порядок отображения дается для этой новой версии рабочего проекта XML Information Set. А пока новая версия XML Information Set еще не реализована, члены W3C могут сверяться с внутренней версией соответствующей рабочей группы по адресу http://www.w3.org/XML/Group/1999/09/WD-xml-infoset-19990915.html (только для членов).

C Словарь (Обсуждение спецификации)

При переводе спецификации на русский язык для ряда терминов был выбран следующий вариант перевода.

child - непосредственный потомок
context position - положение в контексте
context node - узел контекста
descendant - потомок
document element - элемент документа
forward axis - прямая ось
information item - информационный элемент (в XML Information Set)
location path - путь адресации
location step - шаг адресации
node-set - набор, множество узлов
node-test - правило проверки узлов
non-terminal - незавершенный конструктив
principal node type - основной тип узлов
processing instruction - инструкция обработки (XML)
production - сценарий
proximity position - положение близости
reverse axis - обратная ось
symbol - грамматическая конструкция (XML)
token - лексема
validating processor - проверяющий процессор
variable binding - привязка переменной контекста

Если у вас возникли какие-либо замечания, мы будем рады их получить по адресу radik.usmanov@gmail.com.