Przykład dobrze sformatowanego dokumentu XML w pliku ‘heksagramy.xml’. Jego plik DTD podający reguły, które muszą spełniać dane zapisywane w pliku XML znajduje się w pliku ‘heksagramy.dtd’.

Przykład pracy z XML

Obiekt zapisywany musi spełniać warunki określone w specyfikacji JavaBeans. Pola zapisywane muszą być public

Klasa PiesXML

Klasa PiesXML – została szczegółowo opisana w tekście klasy.

package aderby;

import java.beans.*;
import java.io.*;
import java.util.*;
import javax.xml.stream.*;

public class PiesXML implements Serializable {
    private static final long serialVersionUID = -4141106299221795788L;
    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    public String imie;//imie psa
    public long czas = 0L;//czas pomiaru
    public double temp = 0.0d;//zmierzona temperatura
    private File plik;//plik z danymi pomiaru

    public PiesXML() {
        this("Pies");
    }

    public PiesXML(String imie) {
        this.imie = imie;
    }

    public synchronized void addPropertyChangeListener(
            PropertyChangeListener list) {
        pcs.addPropertyChangeListener(list);
    }

    public synchronized void removePropertyChangeListener(
            PropertyChangeListener list) {
        pcs.removePropertyChangeListener(list);
    }

    public String getImie() {
        return imie;
    }

    public void setImie(String imie) {
        this.imie = imie;
    }

    public long getCzas() {
        return czas;
    }

    public void setCzas(long czas) {
        this.czas = czas;
    }

    public double getTemp() {
        return temp;
    }

    /**
     * @param temp      temeperatura
     * @param fireEvent czy poinformowac o zdarzeniu i zapisać plik (true)
     *                  czy tylko zmienic temerature(false)
     */
    public synchronized void setTemp(double temp, boolean fireEvent) {
        if (fireEvent) {
            double oldValue = this.temp;
            this.temp = temp;
            write();
            pcs.firePropertyChange("temp zmieniona", oldValue,
                    temp);
        } else {
            this.temp = temp;
        }
    }

    /**
     * Metoda używa StAX do zapisania aktualnego stanu psa do pliku
     *
     * @return - zwraca true jeśli zapis został wykonany, false - 
     * w przeciwnym wypadku
     */
    public boolean write() {
        //podaje czas w milisekundach
        czas = (new GregorianCalendar()).getTimeInMillis();
        //tworzy nazwe pliku. Umieszczenie czasu w nazwie
        //zapobiega powtorzeniu sie nazwy,
        plik = new File("C:/Przyklady/" + imie + czas + ".xml");
        //Zapisanie danych
        XMLOutputFactory xof = XMLOutputFactory.newInstance();
        FileWriter fw;
        XMLStreamWriter xsw;
        try {
            fw = new FileWriter(plik);
            xsw = xof.createXMLStreamWriter(fw);
            xsw.writeStartDocument("1.0");
            xsw.writeStartElement("pies");
            //-
            xsw.writeStartElement("imie");
            xsw.writeCharacters(this.imie);
            xsw.writeEndElement();
            //-
            xsw.writeStartElement("czas");
            xsw.writeCharacters(Long.toString(czas));
            xsw.writeEndElement();
            //-
            xsw.writeStartElement("temp");
            xsw.writeCharacters(Double.toString(this.temp));
            xsw.writeEndElement();
            //-
            xsw.writeEndElement();
            xsw.flush();
            xsw.close();
        } catch (IOException e) {
            System.out.println("Dane nie zapisane");
            return false;
        } catch (XMLStreamException e) {
            System.out.println("Błąd w strumieniowaniu pliku");
            return false;
        }
        //zamkmniecie strumieni
        try {
            xsw.close();
        } catch (XMLStreamException e) {
            e.printStackTrace();
        }
        try {
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * Odczytanie danych z pliku. Ponieważ zapisujemy dane tego 
     * samego obiektu
     * to możemy odczytać tylko ostatni stan.
     *
     * @return zwraca obiekt bedacy ostatnim stanem psa
     */
    public PiesXML read() {
        PiesXML pies = null;
        XMLInputFactory xif = XMLInputFactory.newInstance();
        FileReader fr = null;
        XMLStreamReader xsr = null;
        try {
            if (plik.exists()) {
                fr = new FileReader(plik);
                xsr = xif.createXMLStreamReader(fr);
                while (xsr.hasNext()) {
                    int eventType = xsr.getEventType();
                    switch (eventType) {
                        case XMLStreamConstants.START_ELEMENT:
                            String elName = xsr.getLocalName();
                            if (elName.equals("imie")) {
                                pies = new PiesXML();
                                pies.setImie(xsr.getElementText());
                            }
                            if (elName.equals("czas")) {
                                Objects.requireNonNull(pies).setCzas(
                                        Long.parseLong(xsr.getElementText()));
                            }
                            if (elName.equals("temp")) {
                                Objects.requireNonNull(pies).setTemp(
                                  Double.parseDouble(xsr.getElementText()),
                                    false);
                            }
                            break;
                        case XMLStreamConstants.END_ELEMENT:
                            elName = xsr.getLocalName();
                            if (elName.equals("imie")) {
                                return pies;
                            }
                            break;
                    }
                    xsr.next();
                }
            }
        } catch (IOException e) {
            System.out.println("Błąd w odczycie pliku");
        } catch (XMLStreamException e) {
            System.out.println("Błąd w strumieniowaniu pliku");
        }
        if (xsr != null) {
            try {
                xsr.close();
            } catch (XMLStreamException e) {
                e.printStackTrace();
            }
        }
        if (fr != null) {
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return pies;
    }

    /**
     * poniewaz dane XML będziemy zapisywali jako Clob, a metoda setClob
     * przyjmuje jako obiekt nie plik a reader, w związku z tym
     * ta metoda zwraca stosowny obiekt Reader (do ostatniego pliku ze stanem
     * psa)
     *
     * @return obiekt Reader
     */
    public Reader read2() {
        FileReader fr = null;
        try {
            if (plik.exists()) {
                fr = new FileReader(plik);
            }
        } catch (IOException e) {
            System.out.println("Błąd w odczycie pliku");
        }
        return fr;
    }

    @Override
    public String toString() {
        return imie + "  " + czas + "  " + temp;
    }
}

Klasa R060

Klasa uruchamiająca R060 – została szczegółowo opisana w tekście klasy.

        XMLEncoder e = new XMLEncoder(new BufferedOutputStream(
           new FileOutputStream("aderby/src/resources/xmls/Pies.xml")));
        //tworzymy psa
        PiesXML pies = new PiesXML("Nutka");
        //zmieniamy mu temperature. Zmiana powoduje zapisanie pliku
        //przy użyciu StAX
        pies.setTemp(37.0, true);
        //sprawdzamy
        System.out.println(pies);
        //zapisujemy obiekt
        e.writeObject(pies);
        e.close();
        XMLDecoder d = new XMLDecoder(new BufferedInputStream(
            new FileInputStream("aderby/src/resources/xmls/Pies.xml")));
        //Pies zmartwychwstaje
        PiesXML result = (PiesXML) d.readObject();
        d.close();
        //sprawdzamy
        System.out.println(result);
        //Zajrzyj do pliku Pies.xml

Po uruchomieniu klasy R060 na konsoli zobaczymy:

Nutka  1575623854419  37.0
Nutka  1575623854419  37.0

W folderze c:/Przyklady pojawi się plik XML z zapisem aktualnej temperatury.

Pliki do ściągnięcia

Plik R060.zip (klasa)
Plik PiesXML.zip (klasa)
Plik heksagramy.zip (plik XML i plik DTD)
Aktualny (tworzony narastająco) plik module-info.java
Aktualny (tworzony narastająco) plik DerbyUtil.java
Pliki tworzone narastająco zastępują poprzednie pliki o tej samej nazwie i działają dla wszystkich wcześniej opublikowanych przykładów we wszystkich wpisach w projekcie. W przypadku pliku module-info.java może być potrzebne skreślenie niepotrzebnych wpisów.