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