Элементы catalog, productline и product
В первой строке содержится объявление корневого элемента catalog:
<!ELEMENT catalog (product_line)*>
Это объявление достаточно очевидное: в нем указывается, что catalog может состоять из любого количества элементов productJ i ne.
Элемент product_line тоже очень просто устроен, но в отличие от элемента catal og у него имеется атрибут name:
<!ELEMENT product_line (product)* >
<!ATTLIST product_line
name CDATA #IMPLIED>
В объявлении атрибута name элемента productjine указано, что этот атрибут не является обязательным (#IMPLIED). Но информация о принадлежности товара (элемент product) к некоторой серии товаров (элементу productjine) не имеет смысла, если мы не знаем названия этой серии. Поэтому соответствующий атрибут, name, мы сделаем обязательным. Внести это изменение несложно:
<!ATTLIST productjline
name CDATA #REQUIRED>
Следующее объявление — наиболее содержательная часть этого определения DTD [Photo — фотография, clip — клип. — Примеч. перев. ]:
<!ELEMENT product(name|description|price|
quantity_in_stock|photo| onsale_date|clip)* >
В таком виде это объявление подразумевает, что элемент product может содержать любое (в том числе нулевое) количество любых перечисленных здесь элементов. Это не соответствует фактической организации каталога на сайте XMLGifts.com. Также здесь не учитываются сведения об авторах книг (для элементов Books) и исполнителях (для элементов CDs). Такие промашки часто случаются, если используется недостаточно большой фрагмент исходных данных, для которых вы составляете DTD. Полностью исправленное объявление элемента product выглядит следующим образом:
<!ELEMENT product name,author* , artist*,
description,price,quantity_in_stock,image*,
onsale_date?,clip*>
ПРИМЕЧАНИЕ
Обратите внимание, что в исправленной версии объявления элемента product указано, что элементы name, description, quantity_m_stock могут встречаться в одном элементе product только один раз. Заметим также, что они обязательно должны присутствовать в этом элементе. Далее обратите внимание, что элемент photo (фотография) был переименован в image (изображение) для большей общности.
Хотя получившееся определение DTD не идеально и, возможно, не учитывает все особенности каждого товара, все же это неплохое «первое приближение». Поскольку оно было сконструировано для конкретного типа документа, а не как DTD общего назначения, мы можем позволить себе пересматривать DTD по мере изменения каталога. Всегда предпочтительнее (и проще) начинать с более обобщенного определения DTD и добавлять к нему новые элементы по мере надобности. Этот метод называется аддитивным уточнением (additive refinement). Противоположный метод уточнения DTD, который сводится к удалению лишних объявлений элементов, называется субтрактивным уточнением (subtractive refinement).
После определения элемента product в DTD определяется атрибут id этого элемента:
<!ATTLIST product
id CDATA #IMPLIED>
Как и с атрибутом name элемента product_line, в каталоге у каждого товара должен быть однозначный идентификатор, поэтому следует сделать этот атрибут обязательным. Кроме того, чтобы гарантировать уникальность значения каждого атрибута id, то есть идентификатора каждого товара, тип атрибута должен быть ID. Исправленное объявление атрибута id выглядит следующим образом:
<!ATTLIST product
id ID #REQUIRED>
Кроме определения товара по его уникальному идентификатору также мы хотели бы иметь возможность отыскать этот товар по ключевым словам. Для этого мы добавим в элемент product еще один атрибут, keywords [Keyword — ключевое слово (характеризующее товар) — Примеч перев.]:
<!ATTLIST product
keywords CDATA #IMPLIED>
В нашем представлении значение атрибута keywords — это список с разделенными запятыми элементами, который можно использовать для поиска и группировки.