Po uwagach studentów zmiany w schemacie (proszę uaktualnić):
http://www.mimuw.edu.pl/%7Eczarnik/xml/OPERACJE
.
insertVar
atrybut to
zmienił nazwę na var
, jak w pozostałych
operacjach. W schemacie wspólne atrybuty zostały wydzielone do grupy.
Main
.ns
oznacza przestrzeń nazw o pustym identyfikatorze
(a nie brak atrybutu). Jest to zgodne z wartością stałej
NULL_NS_URI.
W związku z tym nieznacznie zmienił się opis operacji createTree
i moveToChild
.
Należy napisać program w Javie, który czytając w trybie SAX plik z listą operacji, wykonuje zadane operacje na drzewach DOM. Jednocześnie do innego pliku zapisywane są logi z wykonania operacji.
Klasa wykonywalna programu powinna nazwyać się Main
.
Program uruchamiany będzie z dwoma parametrami: ścieżką do pliku z operacjami i ścieżką do pliku z logami.
Program operuje na zmiennych, które wskazują węzły (zawsze elementy) w drzewach DOM. Zmienne identyfikowane są nazwami.
Każda operacja może odnieść sukces lub porażkę. Porażka występuje wtedy, gdy nie są spełnione warunki niezbędne do wykonania operacji (jak opisano poniżej przy operacjach) lub podczas próby jej wykonania wyrzucany jest wyjątek (np. brak pliku). W przypadku porażki jednej operacji (także wyłapanego wyjątku) należy wykonywać kolejne operacje, nie przerywać programu.
Całe przetwarzanie (zarówno SAX jak i DOM) ma być namespace aware.
Program powinien zachowywać przestrzenie nazw w węzłach kopiowanych poleceniem
insertVar
oraz parsowanych poleceniem insertContent
,
a także zachowywać przestrzenie nazw w poddrzewie podczas „spłaszczania”
dokumentu poleceniem remove
.
Istotne jest to, aby w dokumentach wypisanych poleceniem saveToFile
nazwy elementów i atrybutów należały do tych samych przestrzeni nazw, co przy wczytywaniu.
Nie ma obowiązku zachowywania tych samych prefiksów.
Plik z operacjami może nie zmieścić się w pamięci. Natomiast można przyjąć, że w pamięci zmieszczą się wszystkie drzewa DOM (tzn. w przypadku braku pamięci program ma prawo zachować się w dowolny sposób).
Plik z operacjami jest dokumentem XML zgodnym ze schematem operacje.xsd. Program powinien sprawdzić poprawność strukturalną dokumentu. W przypadku niezgodności powinien się zakończyć ze stosownym komunikatem, nie wykonując pozostałych do końca poleceń.
Wszystkie elementy definiujące operacje znajdują się w przestrzeni nazw http://www.mimuw.edu.pl/%7Eczarnik/xml/OPERACJE
.
Jedynie element insertContent
może zawierać podelementy i atrybuty z innych przestrzeni nazw.
Lista operacji zawiera kolejne definicje operacji, każda w kolejnym elemencie XML.
Nazwa elementu to nazwa operacji, zgodnie z poniższym opisem, a w atrybutach podane są parametry operacji.
Ponadto element może posiadać atrybut id
, który identyfikuje operację w logach.
Element insertContent
posiada też zawartość.
Operacje readFromFile
i createTree
tworzą nowe zmienne (lub nadpisują istniejące).
Pozostałe operacje kończą się porażką jeśli zmienna, której używają, nie została wcześniej utworzona.
Wczytanie dokumentu z pliku do drzewa DOM i przypisanie na podaną zmienną. Po wczytaniu zmienna wskazuje na element główny dokumentu. Jeśli zmienna istniała już wcześniej, jej dotychczasowa wartość jest zastępowana.
Parsowanie ma być namespace aware i niewalidujące. Operacja ponosi porażkę w przypadku braku dostępu do pliku bądź błędów podczas parsowania.
var
– nazwa zmiennej, której przypisywane jest wczytane drzewo. Atrybut obowiązkowy.path
– ścieżka do pliku, który należy wczytać. Atrybut obowiązkowy.Zapisanie drzewa DOM wskazywanego przez zmienną do podanego pliku. Wartość zmiennej nie jest zmieniana. Plik jest nadpisywany.
var
– nazwa zmiennej wskazującej na drzewo. Obowiązkowy.path
– ścieżka do pliku, do którego należy zapisać dokument. Obowiązkowy.document
–
Równy yes
lub no
, domyślnie przyjmujemy no
.
Dla yes
do pliku wypisywany jest cały dokument.
Dla no
wypisywane jest jedynie bieżący element wraz z poddrzewem.
encoding
–
kodowanie znaków, w jakim należy zapisać dokument. Jeśli nie występuje, należy przyjąć
domyślne kodowanie systemu.
Utworzenie nowego drzewa (dokument z pustym elementem głównym) i przypisanie na podaną zmienną. Po utworzeniu zmienna wskazuje na element główny dokumentu. Jeśli zmienna istniała już wcześniej, jej dotychczasowa wartość jest zastępowana.
var
– nazwa zmiennej, na którą przypisywane jest utworzone drzewo. Obowiązkowy.localName
– lokalna część nazwy elementu głównego. Obowiązkowy.ns
–
identyfikator przestrzeni nazw, w której ma znaleźć się element główny.
Napis pusty oznacza przestrzeń nazw o pustym identyfikatorze. Atrybut obowiązkowy.
prefix
–
prefiks nazwy elementu.
Jeśli prefix
nie występuje, element ma znaleźć się w domyślnej przestrzeni nazw.
Walidacja dokumentu wskazywanego przez zmienną (całego dokumentu, nie poddrzewa) względem podanego schematu. Należy założyć, że plik ze schematem nie jest zmieniany w trakcie działania programu.
Operacja odnosi sukces, jeśli dokument jest zgodny ze schematem. Operacja kończy się porażką jeśli dokument nie jest zgodny ze schematem (w logach należy wypisać komunikat od walidatora) lub podczas walidacji występuje błąd.
var
– nazwa zmiennej wskazującej drzewo. Obowiązkowy.schema
– ścieżka do pliku ze shcematem. Obowiązkowy.Przesunięcie wskaźnika zmiennej do rodzica. Jeśli wskaźnik jest już w elemencie głównym, operacja ponosi porażkę a wskaźnik zostaje w miejscu.
var
– nazwa zmiennej, na której operujemy. Obowiązkowy.Przesunięcie wskaźnika zmiennej do sąsiedniego elementu, odpowiednio poprzedzającego i następnego. Jeśli takiego nie ma, operacja ponosi porażkę a wskaźnik zostaje w miejscu.
var
– nazwa zmiennej, na której operujemy. Obowiązkowy.Przesunięcie wskaźnika zmiennej do elementu, który jest dzieckiem bieżącego elementu.
var
– nazwa zmiennej, na której operujemy. Obowiązkowy.localName
– lokalna część nazwy elementu. Jeśli nie występuje, bierzemy pod uwagę podelementy o dowolnej nazwie.ns
–
identyfikator przestrzeni nazw elementu.
Jeśli występuje, bierzemy pod uwagę tylko elementy z podanej przestrzeni nazw.
Napis pusty oznacza przestrzeń nazw o pustym identyfikatorze.
Jeśli ns
nie występuje, bierzemy pod uwagę podelementy
z dowolnej przestrzeni nazw.
n
–
numer podelementu (numerujemy od 1), atrybut obowiązkowy.
Wskaźnik ma przejść do n-tego podelementu spełniającego warunki związane z nazwami.
Jeśli nie ma takiego elementu, operacja ponosi porażkę, a wskaźnik nie przesuwa się.
Wstawienie do drzewa węzłów podanych bezpośrednio w definicji operacji.
Zawartość insertContent
ma zostać sparsowana i wstawiona do drzewa DOM, za ostatnim dzieckiem bieżącego elementu.
Uwzględnione mają być wszystkie elementy (wraz z atrybutami) i węzły tekstowe, należy zachować przestrzenie nazw.
Zawartość ma zostać sparsowana rekurencyjnie, z zachowaniem struktury XML. Należy pominąć komentarze i instrukcje przetwarzania.
Wstawione mają być także atrybuty elementu insertContent
, o ile ich identyfikator przestrzeni nazw jest niepusty i różny od
http://www.mimuw.edu.pl/%7Eczarnik/xml/OPERACJE
. Gdyby atrybuty już istniały, mają zostać nadpisane.
var
– nazwa zmiennej, na której operujemy. Obowiązkowy.Wstawienie do drzewa elementu wskazywanego przez inną zmienną. Do bieżącego węzła, za ostatnim dzieckiem ma zostać wstawiona kopia elementu wskazywanego przez drugą zmienną i całego jego poddrzewa.
var
– nazwa zmiennej, do której dodajemy podelement. Obowiązkowy.from
– nazwa zmiennej, z której element kopiujejmy. Obowiązkowy.Usunięcie z drzewa elementu wskazywanego przez zmienną. Jeśli jest to element główny, operacja ma odnieść porażkę. Po usunięciu zmienna ma wskazywać rodzica usuniętego elementu.
var
– nazwa zmiennej. Obowiązkowy.deep
–
Równy yes
lub no
, domyślnie przyjmujemy no
.
Dla yes
usuwane jest całe poddrzewo.
Dla no
usuwany jest tylko sam element, a wszystkie jego dzieci są „podnoszone”
poziom wyżej, tzn. zostają wstawione w miejsce usuwanego elementu.
Plik z logami jest zwykłym plikiem tekstowym. Należy go otwierać w trybie dopisywania. Dla każdej operacji w pliku powinien znaleźć się wpis o formacie opisanym poniżej.
Wpis zawiera (napisy w jednym wierszy są rozdzielone pojedynczymi spacjami):
id
),SUCCESS
lub FAIL
,getMessage()
wyjątku lub kilka własnych
słów w przypadku błędu wykrytego przez program),
Program może być napisany w Javie 5.0 lub 6.0.
Program powinien używać domyślnych implementacji SAX i DOM dostępnych poprzez klasy
SAXParserFactory
i DocumentBuilderFactory
, ewentualnie DOMImplementationRegistry
.
Klasy powinny być umieszczone w pakiecie pl.edu.mimuw.ab123456.zad3
, gdzie ab123456
to wydziałowy login studenta.
Należy wysłać archwum ZIP lub TGZ, o nazwie równej loginowi studenta, zawierające:
Opis rozwiązania powinien zawierać:
W kodzie programu należy umieścić krótkie komentarze w kluczowych miejscach (np. przeniesienie dzieci do rodzica), a także komentarze zgodne z konwencjami javadoc dla własnych klas i metod.
W labie do działania DOM Load and Save potrzebne będą dodatkowe biblioteki z implementacją parsera. Zalecam wykorzystanie biblioteki Xerces.
Tu dostępne są pliki jar, które należy dopisać do ścieżki CLASSPATH (nie wiem czy wszystkie, można poeksperymentować). Nie należy wysyłać plików jar wraz z rozwiązaniem. Program powinien w standardowy sposób pobierać dostępną implementację DOM.
Na ocenę wpływ będą miały:
W razie wątpliwości co do treści zadania proszę wysyłać pytania pod adres czarnik@duch.mimuw.edu.pl.
Odpowiedzi na najczęściej pojawiające się pytania i inne uzupełnienia pojawią się na tej stronie. Proszę sprawdzać ją co jakiś czas, na pewno przed wysłaniem pytania.