Электронный магазин на Java и XML

Индексация товаров


Пользуясь приведенным выше кратким обзором интерфейсов Java, дающих доступ к объектной модели документа, мы можем исследовать вопрос о создании

различных структур данных, которые ускорят процесс поиска товаров по каталогу, оставляя в то же время информацию о товарах в формате DOM. Ниже перечислены некоторые структуры данных и функциональные возможности, которые нам нужны:

перечень категорий product_line (серий товаров) каталога;

перечень всех товаров каждой серии;

быстрый поиск информации о конкретном товаре (содержимого элемента product) по указанному идентификатору товара (id);

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

быстрый поиск товаров по выбранным ключевым словам.

Метод scanCatalog, как показано в листинге 3.6, создает структуры данных, удовлетворяющие этим требованиям. Эти структуры данных — массивы типа String с именами productLineNames и keywords и объекты Hashtable с именами productLi neHT, productHT и prodByKeyHT. Мы используем классы коллекций, совместимые как с пакетом JDK Java 1.1, так и с JDK Java 1.2, поскольку (на момент написания книги) некоторые процессоры сервлетов до сих пор используют библиотеки Java 1.1.

Метод scanCatal og вызывается сразу же после того, как конструктор этого класса (листинг 3.4) завершил разбор файла XML. Заметим, что в методе scanCatalog первый метод, примененный к корневому элементу (гЕ), — это метод normalize(). Причина этого заключается в том, что у анализатора Sun имеется свойство воспринимать символы возврата каретки и дополнительные пробелы в тексте (которые авторы, пишущие на XML, часто используют для того, чтобы документ было легче просматривать) так, что этот текст разбивается указанными символами на несколько узлов типа Text. Метод normalize объединяет содержимое всех примыкающих друг к другу узлов Text в один узел Text.

Листинг 3.6. Метод scanCatalog инициализирует различные объекты Hashtable (theCatalog.java)

public void scanCatalog(){




Element rE = catDoc.getDocumentElement();

// the root

rE.normalize();

productLineNL = rE.getElementsByTagName("product_line");

productLineHT = new Hashtable();

productHT = new Hashtable();

prodByKeyHT = new Hashtable();

// note that in contrast to other get methods, getAttributes

// returns "" if the attribute does not exist

int i,j, ct = productLineNL.getLength();

productLineNames = new String[ ct ];

for( i = 0 ; i < ct ; i++ ){

Element plE = (Element)productLineNL.item(i);

productLineNames[i] = plE.getAttribute("name");

NodeList prodNL = plE.getElementsByTagName("product");

productLineHT.put( productLineNames[i], prodNL ); // node list

int pct = prodNL.getLength();

System.out.println( productLineNames[i] + " ct " + pct );

for( j = 0 ; j < pct ; j++ ){

Element prodE = (Element)prodNL.item(j) ;

String id = prodE.getAttribute("id");

if( id == null ){

System.out.println("No id - productLine " + productLineNames[i] + " product " + j );

}

else { productHT.put( id, prodE );

// product by id

String keys = prodE.getAttribute("keywords");

if( keys != null ){

addProdByKey( keys, prodE );

}

}

}

}

// end loop over product lines

ct = prodByKeyHT.size();

keywords = new String[ ct ];

i = 0 ;

Enumeration en = prodByKeyHT.keys();

while( en.hasMoreElements()){

keywords[i++] = (String)en.nextElement();

}

shellSortStr( keywords );

}

Метод addProdByKey создает объект prodByKeyHT, как показано в листинге 3.7. Этот метод должен разрешить некое затруднение, связанное с тем, что строка keywds может содержать не одно, а несколько ключевых слов (или фраз), разделенных запятыми. Для решения этой задачи используется класс StringTokenizer, но обратите внимание, что после разбора строки с помощью метода StringTokenizer нужно использовать метод trim, который убирает лишние пробелы перед строкой ключевых слов и после нее. Объект Vector, в котором хранятся ссылки на элементы, сохраняет исходный порядок расположения товаров, то есть такой же, какой был в файле XML.



Листинг 3.7. Метод addProdByKey (TheCatalog.java)

// разбивает строку keywds на отдельные ключевые слова,

// затем создает вектор v или добавляет элемент рЕ к уже

// существующему вектору в prodByKeyHT

private void addProdByKey( String keywds, Element pE ){

StringTokenizer st = new StringTokenizer( keywds, ",");

while( st.hasMoreTokens() ){

String key = st.nextToken().trim();

Vector v = (Vector)prodByKeyHT.get( key );

if( v == null ){

v = new Vector();

prodByKeyHT.put( key, v );

}

v.addElement( pE );

}

}




Содержание раздела