instrukcja (*)
Transkrypt
instrukcja (*)
Technologie XML <Java_&_XML/> Zadania do wykonania: 1) Napisać program w technologii SAX analizujący plik XML (minimalna funkcjonalność – podawanie nazwy i lokalizacji pliku z linii poleceń) w wyniku jego działania, na podstawie danych zawartych w pliku XML należy wygenerować plik HTLM z odpowiednim formatowaniem. Format danych jest wczytywany przez kolejny plik XML, lub (dla wersji na niższą ocenę) zaszyty w kodzie programu. Format pliku z danymi: <artykul jezyk =”#char#”> <autor plec=”k|m”></autor> <temat></temat> <data></data> <tresc> #char# <pogrobienie></pogrobienie>#char#<podkreślenie></podkreślenie> #char# <akapit/> <wypunktowanie> <punkt>#char#</punkt> <punkt>#char#</punkt> </wypunktowanie> </tresc> </artykul> Format pliku z formatem: <format> <autor>#html#</autor> <temat>#html#</temat> <data>#html#</data> <tresc>#html#</tresc> <pogrobienie>#html#</pogrobienie> <podkreślenie>#html#</podkreślenie> <akapit>#html#</akapit> <wypunktowanie> <punkt>#html#</punkt> <punkt>#html#</punkt> </wypunktowanie> </format> Gdzie : | - oznacza alternatywę, #char# - dowolny ciąg znaków (również pusty), #html# - Tagi html wstawiane w miejsce formatu. 2) Napisać program w technologii DOM umożliwiający modyfikację pliku XML w miejscach zawierających konkretne informacje (znacznik + zawartość) na inną zawartość znaczników np. imie „anna” w znaczniku <imie> należy zamienić na „Kasia”; wartość atrybutu „wiek” w znaczku <osoba> należy zamienić z 23 na 25, itd. W najprostszej postaci interfejs programu może sprowadzać się do linii poleceń: „java nazwa_programu [atrybut|znacznik] [znacznik] | [atrybut] [wartość stara] [wartość nowa]” 1 Technologie XML SAX SAX jest uznawany za najszybszy i najmniej pamięciożerny parser XML. Opiera się o reprezentację zdarzeniową, w której otwarcie i zamknięcie każdego dokumentu, znacznika czy występowanie tekstu jest określane jako zdarzenie. Niewątpliwą wadą SAXa jest brak wiedzy o położeniu w pliku XML (stanu). Jest to również dość ciężki do implementacji we własnych projektach interfejs. Pracę z SAXem rozpoczynamy od stworzenia klasy reagującej na zdarzenia (w przykładzie MyHandler). Poniższy przykład opiera się na kodzie zawartym w książce J2EE. Vademecum Programisty. package org.f2k.test; import import import import import import import java.io.IOException; java.io.OutputStreamWriter; java.io.UnsupportedEncodingException; java.io.Writer; org.xml.sax.Attributes; org.xml.sax.SAXException; org.xml.sax.helpers.DefaultHandler; public class MyHandler extends DefaultHandler { StringBuffer textBuffer; static private Writer out; public MyHandler() throws UnsupportedEncodingException{ out = new OutputStreamWriter(System.out, "UTF8"); } public void startDocument() throws SAXException{ nl(); nl(); emit("START OF DOCUMENT"); nl(); emit(""); } public void endDocument() throws SAXException{ nl(); emit("END OF DOCUMENT"); try { nl(); out.flush(); } catch (IOException e) { throw new SAXException("IO Exception", e); } } 2 Technologie XML public void startElement(String namespaceURI, String sName, // nazwa skrócona String qName, // nazwa pełna Attributes attrs) throws SAXException{ echoText(); nl(); emit("ELEMENT: "); String eName = sName; // nazwa elementu // bez uwzględnienia nazwy przestrzeni nazw if ("".equals(eName)) eName = qName; emit("<"+eName); if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { String aName = attrs.getLocalName(i); // nazwa atrybutu if ("".equals(aName)) aName = attrs.getQName(i); nl(); emit(" ATR: "); emit(aName); emit("\t\""); emit(attrs.getValue(i)); emit("\""); } } if (attrs.getLength() > 0) nl(); emit(">"); } public void endElement(String namespaceURI, String sName, // nazwa skrócona String qName // nazwa pełna )throws SAXException { echoText(); nl(); emit("END_OF_ELEM: "); String eName = sName; // nazwa elementu if ("".equals(eName)) eName = qName; emit(""); } public void characters(char buf[], int offset, int len) throws SAXException{ String s = new String(buf, offset, len); if (textBuffer == null) { textBuffer = new StringBuffer(s); } else { textBuffer.append(s); } 3 Technologie XML } // Metody pomocnicze private void echoText() throws SAXException{ if (textBuffer == null) return; nl(); emit("CHARS: |"); String s = ""+textBuffer; emit(s); emit("|"); textBuffer = null; } private void emit(String s) throws SAXException{ try { out.write(s); out.flush(); } catch (IOException e) { throw new SAXException("IO Exception", e); } } private void nl() throws SAXException{ String lineEnd = System.getProperty("line.separator"); try { out.write(lineEnd); } catch (IOException e) { throw new SAXException("IO Exception", e); } } } List. 1. Implementacja SAX. W klasie rozszerzającej DefaultHandler należy zaimplementować metody reagujące na poszczególne zdarzenia w trakcie czytania pliku XML: - void startDocument() – zdarzenie rozpoczęcia dokumentu. - void endDocument() – zdarzenie zakończenia dokumentu. - void startElement( - zdarzenie wykrycia początku znacznika. String namespaceURI, - przestrzeń nazw String sName, - nazwa skrócona znacznika bez nazwy przestrzeni String qName, - nazwa pełna z przestrzenią nazw Attributes attrs) – atrybuty zawarte w znaczniku (lista). - public void endElement(String namespaceURI,String sName, String qName ) – zdarzenie zakończenia znacznika. - void characters(char buf[], int offset, int len) – zdarzenie wykrycia tekstu nie będącego znacznikiem XML (np. wartość zawarta między znacznikami). Wykorzystanie powyższej implementacji modelu SAX może wyglądać następująco: 4 Technologie XML package org.f2k.test; import import import import import java.io.ByteArrayInputStream; java.io.InputStream; javax.xml.parsers.SAXParser; javax.xml.parsers.SAXParserFactory; org.xml.sax.helpers.DefaultHandler; public class SAXTest { SAXTest(String xml){ this(new ByteArrayInputStream(xml.getBytes())); } SAXTest(InputStream stream){ try { DefaultHandler handler = new MyHandler(); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); parser.parse(stream, handler); } catch (Exception e) { e.printStackTrace(); } } } List. 2. Wykorzystanie implementacji SAX. DOM DOM jest parserem, który wykorzystuje się do złożonych modyfikacji XML, czy jego reprezentacji w postaci drzewa obiektu. Jego wadą jest fakt, że jest zasobożerny. Cały dokument jest bowiem przetwarzany w pamięci komputera. W przypadku DOM możemy od razu napisać naszą klasę testową: package org.f2k.test; import import import import import import java.io.ByteArrayInputStream; java.io.InputStream; javax.xml.parsers.DocumentBuilder; javax.xml.parsers.DocumentBuilderFactory; org.w3c.dom.Document; org.w3c.dom.NodeList; public class DOMTest { public DOMTest(String xml){ this(new ByteArrayInputStream(xml.getBytes())); } public DOMTest(InputStream stream){ 5 Technologie XML try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(stream); NodeList names = document.getElementsByTagName("name"); for(int i=0; i < names.getLength(); i++){ System.out.println(names.item(i).getTextContent()); } } catch (Exception e) { e.printStackTrace(); } } } List.3. Przykład wykorzystania modelu DOM. Nasz test wyszukuje w dokumencie XML węzły o nazwie „name” i wyświetla ich zawartość. Jak widać pobieranie elementów oraz ich modyfikacja odbywać się może przez pola klasy Document należącej do pakietu org.w3c.dom.*. Dokładny opis szerokiej listy metod tej klasy można zleźć na stronie: http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/Document.html Oraz opis elementu (klasy) Node: http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/Node.html 6