ровно одного элемента
>с
,
или последовательностью, состоящей из одного или более элементов
>d
.
Помимо этого, формальные правила могут использовать при записи другие формальные правила.
Пример
>((a | b), (с | d))
задает содержимое, первым элементом которого является >a
или >b
, вторым — элемент >с
или >d
.
Содержимое элементов может также включать символьные данные, которые обозначаются при помощи ключевого слова >#PCDATA
(parsable character data — разбираемые символьные данные).
Пример
>
означает, что элемент >product
должен содержать только символьные данные.
Помимо текста элементы могут также включать в себя другие элементы. Содержимое такого типа называется смешанным. Формальные правила смешанного содержимого должны всегда иметь вид >(#PCDATA | ... | ... ) *
.
При помощи формальных правил можно точно и гибко задавать логическую структуру элементов документа. В качестве примера приведем определения элементов для нашего документа с рекламным объявлением.
Пример
Предположим, мы хотим определить документ со следующей логической структурой:
□ корневым элементом документа является элемент >advert
;
□ элемент >advert
содержит последовательность, состоящую из нескольких элементов product и одного элемента >classified
, который может быть пропущен;
□ элемент >product
может содержать текст и другие элементы >product
в любом порядке;
□ элемент >classified
не имеет содержимого.
Документ соответствующей логической структуры может быть задан следующим образом.
Листинг 1.4
>
>
>
>
>
>]>
>
>
> Покупайте наших слонов!
>
>
>
Определению элемента соответствует EBNF-продукция >elementdecl
:
>[45] elementdecl ::= ''
Нетерминал >contentspec
, следующий через пробельное пространство за именем элемента, определяет тип содержимого, которое может иметь этот элемент:
>[46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
Строка ">EMPTY
" соответствует пустому элементу, ">ANY
" — любому содержимому, нетерминал >Mixed
— смешанному содержимому, >children
— содержимому, которое определяется формальными правилами.
>[47] children ::= (choice | seq) ('?' | '*' | '+')?
>[48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
>[49] choice ::= '(' S? cp ( S? '|' S? cp )+ S? ')'
>[50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
>[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
> | '(' S? '#PCDATA' S? ')'