ZAWWW-2st1.2-l01.tresc-1.0

From Studia Informatyczne

Zaawansowane aplikacje WWW - laboratorium

Przetwarzanie XML (część 1)

Celem ćwiczenia jest przygotowanie aplikacji w języku Java, która będzie służyła do stworzenia dokumentu XML za pomocą Java DOM API. Generowany dokument będzie zawierał spis części komputerowych wraz z ich cenami i stanami magazynowymi. Aplikacja powinna umożliwiać dodawanie i usuwanie części, wyświetlanie spisu części oraz transformację i zapis drzewa DOM do pliku XML. Do wykonania ćwiczenia wykorzystane zostanie środowisko programistyczne Eclipse SDK 3.1 (do pobrania z http://www.eclipse.org) Wymagane jest środowisko J2SE 1.4.2 (lub wyższe).

Struktura drzewa DOM dla przechowywania informacji o częściach została przedstawiona na poniższym rysunku.

Image:ZAWWW-2st1_2-l01_tresc-1_0_01.png

<?xml version="1.0"
  encoding="UTF-8"?>
<computer_parts>
  <part ID="10">
    <name>procesorX</name>
    <price>450</price>
    <quantity>
      <poznan>35</poznan>
      <warszawa>24</warszawa>
    </quantity>
  </part>
  <part ID="25">
    <name>mysz</name>
    <price>65</price>
    <quantity>
      <poznan>5</poznan>
      <warszawa>16</warszawa>
    </quantity>
  </part>
  ...
</computer_parts>

1. Uruchom środowisko Eclipse. Na ekranie wyświetlone zostanie okienko z pytaniem o przestrzeń roboczą (ang. workspace), czyli katalog dyskowy, który będzie używany w bieżącej sesji programu Eclipse. Załóżmy, że tym katalogiem będzie c:\programy. Jeśli taki katalog nie istniał, zostanie on założony automatycznie.

Image:ZAWWW-2st1_2-l01_tresc-1_0_02.png


2. Z menu głównego wybierz File->New->Project.

3. Wybierz typ kreatora Java Project. Kliknij przycisk Next >.

Image:ZAWWW-2st1_2-l01_tresc-1_0_04.png

4. Podaj nazwę projektu, np. „xmllab1". Kliknij przycisk Next >.

Image:ZAWWW-2st1_2-l01_tresc-1_0_05.png

5. Kolejne okienko pozwala na zdefiniowanie dodatkowych lub zmianę istniejących ustawień dla projektu. Dla budowanej aplikacji wystarczy domyślna konfiguracja. Kliknij przycisk Finish.

Image:ZAWWW-2st1_2-l01_tresc-1_0_06.png

6. Z menu głównego wybierz Window->Open Perspective->Java. (Ta czynność nie powoduje otwarcia żadnego, nowego okienka).

Image:ZAWWW-2st1_2-l01_tresc-1_0_07.png

7. Zamknij zakładkę Welcome w głównym oknie (jeśli była otwarta).

Image:ZAWWW-2st1_2-l01_tresc-1_0_08.png

8. Kliknij prawym przyciskiem myszy na nazwie projektu w zakładce Package Explorer. Z menu kontekstowego wybierz New->Class.

Image:ZAWWW-2st1_2-l01_tresc-1_0_09.png

9. Podaj nazwę pakietu, np. myXMLpackage oraz nazwę klasy, np. Shop. Zaznacz opcję public static void main(String [] args). Kliknij przycisk Finish.

Image:ZAWWW-2st1_2-l01_tresc-1_0_10.png

10. Postępując podobnie jak w punktach 8-9, utwórz klasę XMLHandler. Uwaga! Nie zaznaczaj opcji public static void main(String [] args).


11. Klasa XMLHandler będzie odpowiedzialna za przechowywanie dokumentu XML w postaci drzewa DOM oraz za operacje wykonywane na tym dokumencie. Konstruktor klasy będzie tworzył nowy dokument XML. Wprowadź następujący kod do pliku tej klasy.

package myXMLpackage;

import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileOutputStream;

public class XMLHandler {
    Document xmlDoc;

    public XMLHandler() {
        DocumentBuilderFactory factory =
                               DocumentBuilderFactory.newInstance();
        try {
      DocumentBuilder parser = factory.newDocumentBuilder();
      xmlDoc = parser.newDocument();
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
}

12. Dokument XML musi posiadać główny węzeł, który obejmuje całość dokumentu. W przypadku modelowanej aplikacji jest to węzeł „computer_parts". Dodaj do klasy XMLHandler poniższą metodę odpowiedzialną za jego utworzenie.

public void addRoot() {
Element root = (Element) xmlDoc.createElement("computer_parts");
xmlDoc.appendChild(root);
}

13. Kolejnym etapem ćwiczenia jest zdefiniowanie operacji służących do wstawiania i usuwania opisu podzespołów komputerowych z dokumentu XML. Dodaj poniższe definicje metod do klasy XMLHandler.

public void addPart(String r_id, String r_name, String r_price,
                String r_quantity1, String r_quantity2) {
          Node nameNode, priceNode, quantityNode, cityNode;
          Node rootNode = xmlDoc.getDocumentElement();
          Element newPartNode = xmlDoc.createElement("part");
          newPartNode.setAttribute("ID", r_id);
          rootNode.appendChild(newPartNode);

          nameNode = xmlDoc.createElement("name");
          Node newTextNode = xmlDoc.createTextNode(r_name);
          nameNode.appendChild(newTextNode);
          newPartNode.appendChild(nameNode);

          priceNode = xmlDoc.createElement("price");
          newTextNode = xmlDoc.createTextNode(r_price);
          priceNode.appendChild(newTextNode);
          newPartNode.appendChild(priceNode);

          quantityNode = xmlDoc.createElement("quantity");
          newPartNode.appendChild(quantityNode);
          cityNode = xmlDoc.createElement("poznan");
          newTextNode = xmlDoc.createTextNode(r_quantity1);
          cityNode.appendChild(newTextNode);
          quantityNode.appendChild(cityNode);
          cityNode = xmlDoc.createElement("warszawa");
          newTextNode = xmlDoc.createTextNode(r_quantity2);
          cityNode.appendChild(newTextNode);
          quantityNode.appendChild(cityNode);
}

public void delPart(String r_id) {
Node rootNode = xmlDoc.getDocumentElement();
Node partNode, idNode;
NodeList docNodeList = rootNode.getChildNodes();
for (int i = 0; i < docNodeList.getLength(); i++) {
            partNode = docNodeList.item(i);
            idNode = partNode.getAttributes().item(0);
            if (idNode.getNodeValue().equals(r_id)) {
                  rootNode.removeChild(partNode);
                  System.out.println("usunięto część z id=" + r_id);
                  break;
            }
      }
}

14. Użytkownik powinien mieć dostęp do wprowadzonych do dokumentu informacji na temat części komputerowych. Ponadto powinna istnieć możliwość zapisu dokument XML do pliku. Poniżej znajduje się implementacja dwóch metod służących do realizacji tych wymagań. Dodaj te metody do klasy XMLHandler.

public void showXML() {

Node rootNode = xmlDoc.getDocumentElement();
Node myNode;
Element tempElement;
NodeList docNodeList = rootNode.getChildNodes();
String desc;
for (int i = 0; i < docNodeList.getLength(); i++) {
            tempElement = (Element) docNodeList.item(i);
            desc = "[" + tempElement.getAttribute("ID") + "";
            myNode = tempElement.getElementsByTagName("name").item(0);
            desc += myNode.getFirstChild().getNodeValue();
            desc += ", price:";
            myNode = tempElement.getElementsByTagName("price").item(0);
            desc += myNode.getFirstChild().getNodeValue();
            System.out.println(desc);
      }
}
public void saveXML() {
try {
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer t = tf.newTransformer();
            t.transform(new DOMSource(xmlDoc), new StreamResult(
                        new FileOutputStream("wynik.xml")));
      } catch (Exception e) {
            System.out.println(e.toString());
      }
}


15. Budowana aplikacja będzie działała w trybie tekstowym. Po uruchomieniu użytkownik będzie mógł wydawać kolejne polecenia (do momentu wpisania komendy exit, co skutkuje zakończeniem działania programu). Dodaj polecenia importu pakietów i uzupełnij metodę main w klasie Shop.

import java.io.*;
import java.util.StringTokenizer;

...
public static void main(String[] args) {
XMLHandler xml = new XMLHandler();
xml.addRoot();
try {
            BufferedReader in = new BufferedReader(new
                                    InputStreamReader(System.in));
          String input = "";
          while(true) {
        System.out.print("> ");
        input = in.readLine();
        if (input.equals(""))
                      continue;
              if ("exit".equals(input))
                  break;
              else
                      parseJob(input, xml);
          }            
      } catch(Exception e) {
          System.out.println(e.getMessage());
}
}

16. Dodaj metodę, która będzie realizowała polecenia wpisywane przez użytkownika. Polecenie add wymaga podania pięciu parametrów opisujących część (identyfikator, nazwa, cena, ilość w sklepie w Poznaniu, ilość w sklepie w Warszawie) oddzielonych znakiem spacji. Polecenie del wymaga podania identyfikatora usuwanej części. Polecenie show wyświetla aktualną listę części, save zapisuje dane do pliku XML. Dodaj poniższy kod do klasy „Shop".

public static void parseJob(String r_input, XMLHandler r_xml) {
          StringTokenizer st = new StringTokenizer(r_input," ");
          String command = st.nextToken();
          if (command.equalsIgnoreCase("add"))
                r_xml.addPart(st.nextToken(), st.nextToken(), st.nextToken(),
                          st.nextToken(), st.nextToken());
          else if (command.equalsIgnoreCase("del"))
              r_xml.delPart(st.nextToken());
      else if (command.equalsIgnoreCase("show"))
          r_xml.showXML();
      else if (command.equalsIgnoreCase("save"))
    r_xml.saveXML();
}


17. Przejdź do edycji klasy Shop. Z głównego menu wybierz Run-> Run. W panelu Configurations zaznacz Java Application kliknij przycisk New.

18. Uruchom aplikację przez kliknięcie przycisku Run.

19. Przetestuj działanie programu używając wbudowanej w środowisko Eclipse konsoli. Dodaj klika podzespołów do dokumentu, wyświetl je, usuń wybrane, zapisz do pliku.

20. Zapisany plik XML możesz znaleźć w katalogu projektu (przy ustawieniach użytych w ćwiczeniu, ścieżka do pliku to C:\programy\xmllab1\wynik.xml). Sprawdź zawartość pliku, np. używając przeglądarki internetowej.

Image:ZAWWW-2st1_2-l01_tresc-1_0_14.png