Apache Derby: XML
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.java
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_XML_descr.java
package aderby.types; import aderby.PiesXML; import java.beans.*; import java.io.*; public class R060_XML_descr { public static void main(String[] args) throws FileNotFoundException { 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 } }
Pies.xml
<?xml version="1.0" encoding="UTF-8"?> <java version="16.0.2" class="java.beans.XMLDecoder"> <object class="aderby.PiesXML" id="PiesXML0"> <void class="aderby.PiesXML" method="getField"> <string>imie</string> <void method="set"> <object idref="PiesXML0"/> <string>Nutka</string> </void> </void> <void class="aderby.PiesXML" method="getField"> <string>czas</string> <void method="set"> <object idref="PiesXML0"/> <long>1627728257461</long> </void> </void> <void class="aderby.PiesXML" method="getField"> <string>temp</string> <void method="set"> <object idref="PiesXML0"/> <double>37.0</double> </void> </void> </object> </java>
Po uruchomieniu klasy R060_XML_descr
na konsoli zobaczymy:
Nutka 1669045662027 37.0 Nutka 1669045662027 37.0
W folderze c:/Przyklady pojawi się plik XML z zapisem aktualnej temperatury.
Plik heksagramy.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE heksagramy SYSTEM "heksagramy.dtd"> <heksagramy> <heksagram id1="1" id2="63"> <nazwa>Czhien – Tworzenie</nazwa> <obraz>Niebo nad niebem</obraz> <osad>Posiadasz moc, wynikającą z idealnej harmonii z siłami nieba. Możesz czerpać z niebiańskich zasobów energii, zapewniającej ci bezpieczeństwo. Z tej energii może narodzić się coś nowego, coś wielkiego. Będziesz odgrywał w tym główną rolę. Jeśli starannie się przygotujesz i przemyślisz sprawę i nie będziesz się wahał, zrealizujesz najśmielsze pomysły. Moc nieba będzie odbudowywać i podtrzymywać twoje siły. Twoje zamiary i podjęte czyny będą ewoluować. Początek nowego oznacza koniec czegoś starego. Pamiętaj też – moc nieba może być destrukcyjna, jeśli użyjesz jej niewłaściwy sposób lub do niewłaściwego przedsięwzięcia. Stan mocy nie trwa długo. Wykorzystaj ją teraz. Nie ustawaj w wysiłkach i działaj. </osad> <linia1 id="9">Ten zapis oznacza w każdym przypadku 'dziewięć na linii pierwszej', itd. Obecny czas nie sprzyja nowym przedsięwzięciom, takim jak zakładanie rodziny czy przedsiębiorstwa. Twoje twórcze siły powinny pozostać w ukryciu. Bądź wierny sobie i swoim ideałom, nie zbaczaj z raz obranej drogi. Poczekaj, aż sytuacja się poprawi. Gdybyś zaczął działać teraz trwoniłbyś niepotrzebnie siły. Uporządkuj swoje sprawy. Zajmij się przygotowywaniem i organizowaniem. Czekaj. </linia1> <linia2 id="9">Twórcze siły nieba objawiają się na świecie. Masz przed sobą ważne przedsięwzięcie. Korzystnie będzie zdobyć pomoc innych osób, najlepiej wpływowych. Zbliż się do jednej lub kilku z takich osób. Połącz z nimi siły, a pomogą ci albo nie będą przeszkadzać przy realizacji twojego przedsięwzięcia. </linia2> <linia3 id="9">Jesteś wybrańcem. Siły nieba są z tobą. Tworzysz i ciężko pracujesz we dnie i w nocy. Twój umysł zajęty wielkimi planami jest przeciążony. Grozi ci niebezpieczeństwo, że popełnisz błędy, które będą cię drogo kosztować, że opanowany ambicjami możesz stracić właściwy kierunek działania. Jeśli naprawdę jesteś wielki nie ulegniesz pokusom. </linia3> <linia4 id="9">Jesteś na rozdrożu. Przyszła chwila na podjęcie decyzji. Masz do wyboru wyjście w świat i skupieniu się na pracy dla świata albo wybrać pracę nad doskonaleniem siebie i swego umysłu. Możesz spróbować i jednego i drugiego. A potem sam musisz zdecydować jaką drogę chcesz wybrać. </linia4> <linia5 id="9">Jesteś wybrańcem i uzyskałeś niebiańską harmonię. Masz duży wpływ na ludzi. Jesteś mądry i możesz udzielać rad. Ale nikt nie jest wieczny. Pomyśl o swoich następcach - w domu i swoich przedsięwzięciach. Najlepsi z nich będą ci, których sam wychowasz. </linia5> <linia6 id="9">Nie przekraczaj granic. Nie izoluj się od ludzi. Nie miej zbyt wygórowanych ambicji, nie miej nadmiernego zaufania do własnych sił ani nie lekceważ kompromisów. Nie unoś się dumą. Nie bądź apodyktyczny. Jeśli utracisz kontakt z ludźmi, nawet jeśli jesteś wielkim człowiekiem – upadniesz. </linia6> <wszystkie id="9">Grupa ludzi kompetentnych czeka na twoje przywództwo. Działaj szybko i zdecydowanie, ale łagodnie. Chwila jest bardzo sprzyjająca, ale nie potrwa długo. </wszystkie> </heksagram> .............. </heksagram> <heksagram id1="64" id2="21"> <nazwa>Wei Ci – Przed spełnieniem</nazwa> <obraz>Ogień nad wodą</obraz> <osad>Działania musisz podejmować we właściwym czasie. Nie za późno i nie za wcześnie. Sukces masz przed sobą na wyciągnięcie ręki. Zachowaj czujność do końca. </osad> <linia1 id="6">Na razie jesteś zbyt słaby, żeby walczyć ze swoimi władzami. Przyczaj się. Wykorzystaj czas na zbieranie sił, doskonalenie umiejętności i naukę. </linia1> <linia2 id="9">Na razie nie ryzykuj. Zachowaj ostrożność. Poczekaj. Bądź czujny i przygotowania, do natychmiastowego podjęcia działania. </linia2> <linia3 id="6">Nadszedł czas na podjęcie działań, ale zebrane siły nie są wystarczające. Poniesiesz klęskę, jeśli zaczniesz. Przegrupuj siły. Sprowokuj przeciwnika. Działaj z zaskoczenia. </linia3> <linia4 id="9">Nadszedł czas działania. Masz zebrane wystarczające siły. Walcz. Nabieraj doświadczenia w walce. Niektórzy i tak nie rozumieją o co chodzi. Za jakiś czas zrozumieją, a ty zostaniesz obsypany honorami i zaszczytami. </linia4> <linia5 id="6">Bądź stanowczy i szlachetny. Idź dalej swoją ścieżką. Osiągniesz powodzenie. </linia5> <linia6 id="9">Nadeszły nowe, dobre czasy. Uczcij zmiany. Pilnuj, aby zmiany na lepsze były trwałe. Niech woda sodowa nie uderzy ci do głowy. </linia6> </heksagram> </heksagramy>
Plik heksagramy.dtd
<?xml version="1.0" encoding="UTF-8"?> <!-- DTD dla heksagramy.xml file --> <!ELEMENT heksagramy (heksagram*)> <!ELEMENT heksagram (nazwa, obraz, osad, linia1, linia2, linia3, linia4, linia5, linia6, wszystkie?)> <!ELEMENT nazwa (#PCDATA)> <!ELEMENT obraz (#PCDATA)> <!ELEMENT osad (#PCDATA)> <!ELEMENT linia1 (#PCDATA)> <!ELEMENT linia2 (#PCDATA)> <!ELEMENT linia3 (#PCDATA)> <!ELEMENT linia4 (#PCDATA)> <!ELEMENT linia5 (#PCDATA)> <!ELEMENT linia6 (#PCDATA)> <!ELEMENT wszystkie (#PCDATA)> <!ATTLIST heksagram id1 CDATA #REQUIRED id2 CDATA #REQUIRED > <!ATTLIST linia1 id CDATA #REQUIRED > <!ATTLIST linia2 id CDATA #REQUIRED > <!ATTLIST linia3 id CDATA #REQUIRED > <!ATTLIST linia4 id CDATA #REQUIRED > <!ATTLIST linia5 id CDATA #REQUIRED > <!ATTLIST linia6 id CDATA #REQUIRED > <!ATTLIST wszystkie id CDATA #REQUIRED >
Pliki do ściągnięcia
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.