<xsclass="underline" apply-templates/>
</xsclass="underline" copy>
</xsclass="underline" template>
<xsclass="underline" template match="vertex">
<vertex name="{@name}" connects="{@connects}">
<xsclass="underline" comment>
<xsclass="underline" for-each select="id(@connects)|id(id@connects)/@connects)">
<xsclass="underline" text> </xsclass="underline" text>
<xsclass="underline" value-of select="@name"/>
</xsclass="underline" for-each>
</xsclass="underline" comment>
</vertex>
</xsclass="underline" template>
</xsclass="underline" stylesheet>
<!DOCTYPE vertices SYSTEM "gemini.dtd">
<vertices>
<vertex name="alpha" connects="tau">
<!-- alpha epsilon theta iota tau-->
</vertex>
<vertex name="beta" connects="upsilon">
<!-- beta delta iota kappa upsilon-->
</vertex>
<vertex name="gamma" connects="zeta">
<!-- gamma delta zeta-->
</vertex>
<vertex name="delta" connects="zeta lambda upsilon">
<!-- beta gamma delta zeta iota kappa lambda xi upsilon-->
</vertex>
<vertex name="epsilon" connects="nu mu tau">
<!-- alpha epsilon theta iota mu nu tau-->
</vertex>
<vertex name="zeta" connects="delta gamma">
<!-- gamma delta zeta lambda upsilon-->
</vertex>
<vertex name="theta" connects="tau">
<!-- alpha epsilon theta iota tau-->
</vertex>
<vertex name="iota" connects="tau upsilon">
<!-- alpha beta delta epsilon theta iota kappa tau upsilon-->
</vertex>
<vertex name="kappa" connects="upsilon">
<!-- beta delta iota kappa upsilon-->
</vertex>
<vertex name="lambda" connects="delta xi">
<!-- delta zeta lambda xi upsilon-->
</vertex>
<vertex name="mu" connects="epsilon">
<!-- epsilon mu nu tau-->
</vertex>
<vertex name="nu" connects="epsilon">
<!-- epsilon mu nu tau-->
</vertex>
<vertex name="xi" connects="lambda">
<!-- delta lambda xi-->
</vertex>
<vertex name="tau" connects="alpha theta iota epsilon">
<!-- alpha epsilon theta iota mu nu tau upsilon-->
</vertex>
<vertex name="upsilon" connects="beta iota kappa delta">
<!-- beta delta zeta iota kappa lambda tau upsilon-->
</vertex>
</vertices>
Базовые продукции XPath
В этом разделе мы приведем базовые синтаксические правила языка XPath. Со многими из них мы уже встречались в правилах более высокого уровня, некоторые определены в спецификации для того, чтобы облегчить реализацию лексического разбора XPath-выражений в различных процессорах.
Литералы — это строковые значения, заключенные в одинарные или двойные кавычки. В литералах нельзя использовать символ кавычек, в которые они заключены. Кроме этого, поскольку XPath-выражения чаще всего используются в атрибутах элементов, в них нельзя использовать символы "<" и "&" — они должны заменяться на сущности. Литералам соответствует продукция Literal, определяемая в виде:
[XP29] Literal ::= '"' [^"]* '"' | "'" [^']* "'"
XPath использует десятичную систему счисления. Наборы цифр, соответствующие правилу Digits, могут состоять из цифр от 0 до 9:
[XP31] Digits ::= [0-9]+
Число в XPath состоит из последовательности цифр, которые могут быть разделены точкой, причем точка может стоять как в начале числа (.5), так и в конце (5.). Числу соответствует EBNF-правило Number:
[XP30] Number ::= Digits ('.' Digits?)? | '.' Digits
Оператору умножения соответствует символ "*" и синтаксическое правило MultiplyOperator:
[XP34] MultiplyOperator ::= '*'
Именам переменных, которые используются в XPath, предшествует символ "$". Сами же имена должны удовлетворять продукции QName, которую мы рассматривали в разделе "Расширенные имена".
[XP36] VariableReference ::= '$' QName
Продукция NodeType, использованная в тесте узла (см. раздел "Тесты узлов" данной главы, продукция [XP7]), определяет типы узлов, которые можно проверить при тесте — comment (комментарий), text (текстовый узел), processing-instruction (узел инструкции по обработке) и node (узел любого типа). NodeType записывается следующим образом:
[XP38] NodeType ::= 'comment'
| 'text'
| 'processing-instruction'
| 'node'
Другая конструкция, NameTest, которая также используется в тесте узла, проверяет узлы базового типа оси на соответствие определенному имени. EBNF-правило NameTest имеет следующий синтаксис:
[ХР37] NameTest ::= '*' | NCName ':' '*' | QName
Имя функции в XPath может быть любым корректным XML-именем за исключением тех имен, которые используются для обозначения типов узлов. Правило FunctionName имеет вид:
[XP35] FunctionName ::= QName - NodeType
В целях удобочитаемости, в выражениях можно использовать пробельное пространство. Ему соответствует EBNF-правило ExprWhiteSpace:
[XP39] ExprWhitespace ::= S
Разбор XPath-выражений
Хотя синтаксис языка XPath укладывается в тридцать с небольшим синтаксических правил, реализация интерпретатора XPath-выражений может быть довольно непростой задачей. Для того чтобы хоть как-то упростить ее, в XPath определяются так называемые токены выражения (англ. expression token). Токены — это единицы, из которых состоит выражение. Будучи сами очень простыми, они выстраиваются в более сложные конструкции, образуя, в итоге, выражения.
Примером токенов являются операторы, которым соответствуют продукции Operator и OperatorName:
[XP33] OperatorName ::= 'and' | 'or' | 'mod* | 'div'
[XP32] Operator ::= OperatorName
| MultiplyOperator