[ Pobierz całość w formacie PDF ]
.Jedynafunkcja, do jakiej nie bêdziemy mieli dostêpu, to obs³uga pomijania encji (nieby³a ona po prostu dostêpna w implementacji 1.0 w jakiejkolwiek formie, wiêcnie mo¿e byæ emulowana).Sposób u¿ycia tej klasy przedstawiony jest wprzyk³adzie 3.6.Przyk³ad 3.6.Korzystanie z klasy Parser z SAX 1.0 jako klasy XMLReader z 2.try {// Zarejestruj parser w SAXParser parser =ParserFactory.makeParser("org.apache.xerces.parsers.SAXParser");ParserAdapter myParser = new ParserAdapter(parser);// Zarejestruj procedurê obs³ugi zawartoœcimyParser.setContentHandler(contentHandler);// Zarejestruj procedurê obs³ugi b³êdówmyParser.setErrorHandler(errorHandler);// Przetwórz dokumentmyParser.parse(uri);} catch (ClassNotFoundException e) {System.out.println("Nie znaleziono klasy parsera.");} catch (IllegalAccessException e) {System.out.println("Niewystarczaj¹ce przywileje do za³adowania klasy parsera.");} catch (InstantiationException e) {System.out.println("Niemo¿liwe utworzenie egzemplarza klasy parsera.");} catch (ClassCastException e) {System.out.println("Parser nie ma zaimplementowanego org.xml.sax.Parser");} catch (IOException e) {System.out.println("B³¹d przy wczytywaniu URI: " + e.getMessage());} catch (SAXException e) {System.out.println("B³¹d w przetwarzaniu: " + e.getMessage());}Jeœli Czytelnik dopiero zaczyna poznawaæ interfejs SAX i ma k³opoty zezrozumieniem tego przyk³adu, nie powinien siê martwiæ — w przypadkukorzystania z najnowszej i najlepszej wersji SAX (2.0) prawdopodobnie nigdy niebêdzie trzeba u¿ywaæ kodu podobnego do powy¿szego.Przydatny jest on tylko tam,gdzie konieczne jest korzystanie z parsera 1.SAX XMLReader — wielokrotne u¿ycie a wspó³bie¿noœæJedn¹ z najciekawszych cech Javy jest fakt, ¿e w niezwykle prosty sposób mo¿nawielokrotnie u¿ywaæ tych samych obiektów.Cechê tê posiadaj¹ równie¿ parserySAX.Po utworzeniu egzemplarza XMLReader mo¿liwe jest ci¹g³e jego u¿ywanie iprzekazywanie mu wielu (nawet setek) dokumentów.Kolejne dokumenty lub Ÿród³aInputSources przekazywane s¹ parserowi, zatem mo¿e byæ on wykorzystany doró¿nych zadañ.Parsery nie s¹ jednak wspó³bie¿ne.Kiedy ju¿ rozpocz¹³ siêproces przetwarzania, parsera nie bêdziemy w stanie wykorzystaæ ponowniedopóty, dopóki to pierwsze przetwarzanie nie zostanie zakoñczone.Dla tych zCzytelników, którzy lubi¹ korzystaæ z algorytmów rekurencyjnych, to w³aœniemo¿e stanowiæ pu³apkê.Kiedy spróbujemy u¿yæ parsera wtedy, gdy ten jest akuratw trakcie przetwarzania innego dokumentu, zg³oszony zostanie raczej niemi³ySAXException i ca³e przetwarzanie zostanie zatrzymane.Jaki z tego wynikawniosek? Dokumenty nale¿y przetwarzaæ jeden po drugim, albo — godz¹c siê nawszelkie tego skutki — tworzyæ wiêcej egzemplarzy parsera.Locator w z³ym miejscuKolejn¹ niebezpieczn¹ (a z pozoru niewinn¹) cech¹ zdarzeñ SAX jest faktudostêpniania egzemplarza Locator poprzez wywo³anie metodysetDocumentLocator().W ten sposób aplikacja poznaje Ÿród³o zdarzenia SAX, coumo¿liwia podjêcie decyzji o dalszym przetwarzaniu oraz sposobie reagowania nainne zdarzenia.Jednak¿e to miejsce jest okreœlone poprawnie jedynie na czasistnienia egzemplarza ContentHandler.Po ukoñczeniu przetwarzania Locator niejest ju¿ poprawny (szczególnie wtedy, gdy rozpoczyna siê nastêpneprzetwarzanie).B³êdem pope³nianym przez nowicjuszy jest przechowywaniereferencji do obiektu Locator wewn¹trz zmiennej nale¿¹cej do klasy spozawywo³ania wstecznego:public void setDocumentLocator(Locator locator) {// Zachowanie Locator w klasie poza ContentHandlermojaInnaKlasa.setLocator(locator);}.public metodaInnejKlasy() {// Próba u¿ycia poza ContentHandlerSystem.out.println(locator.getLineNumber());}To bardzo z³y pomys³ — Locator traci znaczenie, bo jesteœmy ju¿ pozaimplementacj¹ ContentHandler.Czêsto korzystanie z takiej zmiennej powodujenie tylko otrzymywanie przez aplikacjê nieprawid³owych informacji, ale równie¿uszkodzenie dokumentu XML.Innymi s³owy, obiektu tego nale¿y u¿ywaæ lokalnie, anie globalnie.W naszej implementacji ContentHandler otrzymany Locatorzachowaliœmy do zmiennej.Nastêpnie moglibyœmy jej u¿yæ w poprawny sposób(np.do podania numerów wierszy, w których napotkaliœmy poszczególneelementy):public void startElement(String namespaceURI, String localName,String rawName, Attributes atts)throws SAXException {System.out.print("startElement: " + localName +" w wierszu " + locator.getLineNumber());if (!namespaceURI.equals("")) {System.out.println(" w przestrzeni nazw " + namespaceURI +" (" + rawName + ")");} else {System.out.println(" nie posiada skojarzonej przestrzeni nazw");}for (int i=0; i
[ Pobierz całość w formacie PDF ]
Darmowy hosting zapewnia PRV.PL