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

       

Создание DOM


В листинге 9.10 показано начало класса NewsModel, включая переменные экземпляра и конструктор. Обратите внимание на то, что здесь присутствуют две коллекции, Hashtable и Nodelist, которые будут «заселены» элементами article, когда завершится создание DOM. Конструктору просто передаются параметры, содержащие путь и имя файла XML. В зависимости от того, какой анализатор XML вы используете, вам может потребоваться несколько изменить инструкции импорта и метод loadXML, показанный в листинге 9.11, но остальные методы должны работать с любым анализатором, потому что они используют интерфейсы org.w3c.dom.

Листинг 9.10. Начало класса NewsModel (NewsModel.java) package com.XmlEcomBook.Chap09;

package com.XmlEcomBook.Chap09;

import java.io.* ; import java.util.* ; import com.sun.xml.tree.* ; import com.sun.xml.parser.Resolver ; import org.xml.sax.* ; import org.w3c.dom.* ;

public class NewsModel { long timestamp ; public String dateStr ; Document doc ; String path, fname ; public boolean usable ; public String lastErr ="no error"; // see locateCategories for creation of following Hashtable clusterHash ; NodeList articleNodeList ;

public NewsModel( String pth, String fn ){ path = pth ; fname = fn ; }

Процесс синтаксического анализа контролируется методом loadXML, как показано в листинге 9.11. Заметьте, что (для сохранения максимально полной информации по отладке) исключения SAXParseException перехватываются по отдельности и подробная информация о причинах возникновения исключения сохраняется в переменной lastErr. Хотя документы XML, содержащиеся на сайте Moveover.com, обычно правильно оформлены, у нас был один случай неправильно оформленного документа — в нем содержался недопустимый символ. В этом случае подробная информация о причинах исключительной ситуации при синтаксическом анализе оказалась очень ценной.

Листинг 9.11. Метод loadXML осуществляет синтаксический анализ (NewsModel.java)

// return true if sucessful - if false, see lastErr public synchronized boolean loadXML( ) { File xmlFile = new File( path, fname ); System.out.println("NewsModel.loadXML start " + xmlFile.getAbsolutePath() ); try { timestamp = xmlFile.lastModified(); dateStr = new Date( timestamp ).toString(); InputSource input = Resolver.createInputSource( xmlFile ); // ... the "false" flag says not to validate (faster) // XmlDocument is in the com.sun.xml.tree package doc = XmlDocument.createXmlDocument (input, false); System.out.println("Created document"); usable = true ; return true ; }catch(SAXParseException spe ){ StringBuffer sb = new StringBuffer( spe.toString() ); sb.append("\n Line number: " + spe.getLineNumber()); sb.append("\nColumn number: " + spe.getColumnNumber() ); sb.append("\n Public ID: " + spe.getPublicId() ); sb.append("\n System ID: " + spe.getSystemId() + "\n"); lastErr = sb.toString(); System.out.print( lastErr ); return false ; }catch( SAXException se ){ lastErr = se.toString(); System.out.println("loadXML threw " + lastErr ); se.printStackTrace( System.out ); return false ; }catch( IOException ie ){ lastErr = ie.toString(); System.out.println("loadXML threw " + lastErr + " trying to read " + xmlFile.getAbsolutePath() ); return false ; } } // end loadXML


Если анализ XML завершился успешно и была создана объектная модель документа, вызывается метод locateCategories. Как показано в листинге 9.12, этот метод получает NodeList — список всех элементов article, и записывает его в переменную articleNodeList. Затем он вызывает метод processArticle для каждого элемента. Метод processArticle строит вектор элементов для каждого значения элемента cluster. Это как раз тот вектор, который выдает заголовки сообщений, если в запросе пользователя указана конкретная тематика.



Листинг 9.12. Метод locateCategories классифицирует заголовки (newsModel.java)

public void locateCategories(){ Element dE = doc.getDocumentElement(); // the root element clusterHash = new Hashtable(); articleNodeList = dE.getElementsByTagName("article"); int act = articleNodeList.getLength(); //System.out.println("Article count: " + act ); for( int i = 0 ; i < act ; i++ ){ Element aE = (Element) articleNodeList.item( i ) ; processArticle( aE ); } }

private void processArticle( Element artE ){ NodeList clusterNL = artE.getElementsByTagName("cluster"); if( clusterNL.getLength() == 0 ) return ; Element clE = (Element)clusterNL.item(0); String clusterStr = clE.getFirstChild().getNodeValue().trim() ; // System.out.println("cluster ct " + clusterNL.getLength() + // " value: " + clusterStr ); Object obj = clusterHash.get( clusterStr ); Vector v = null ; if( obj == null ){ v = new Vector(); clusterHash.put( clusterStr, v ); } else {v = (Vector)obj ; } v.addElement( artE ); }

 




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