V předchozích dílech jsme probrali většinu DOMu, a proto by nebyl špatný
nápad naše znalosti shrnout v nějaké ukázce. Dnes se tedy podíváme na
jednoduchý telefoní seznam v XML v Javě.
22.6.2004 15:00 | Aleš Hakl | přečteno 26776×
Náš telefoní seznam používá grafickou knihovnu Swing a konkrétně komponentu JTable, jedinou zajímavou částí programu je tedy třída PhoneBookTableModel
. Swing se striktně drží MVC modelu, a proto stačí pouze napsat Model, tj. výše uvedenou třídu. Její funkci si tedy dále rozebereme. Náš program bude používat dokument v přibližně takovémto tvaru:
<?xml version="1.0" encoding="UTF-8"?> <phone-book> <person> <first-name>Franta</first-name> <surname>Novák</surname> <phone>+420999123456</phone> <email>franta at novak dot mars</email> </person> </phone-book>
public PhoneBookTableModel() { rowCount = 0; try { DOMImplementation impl = DocumentBuilderFactory.newInstance() .newDocumentBuilder().getDOMImplementation(); doc = impl.createDocument(null,"phone-book",null); } catch (java.lang.Exception ex) { // Nelze vytvorit dokument, nema tedy smysl pokracovat v behu System.out.println("Cannot create Document: "+ex.toString()); System.exit(1); } }
Zde dokument vytváříme jiným způsobem než tím, který jsem popisoval v prvním díle. Nejprve pomocí metody getDOMImplementation() třídy DocumentBuilder
získáme instanci třídy DOMImplementation
, jejíž metodou createDocument() vytvoříme prázdný dokument zadaných vlastností. Parametry jsou: URI jmenného prostoru (nepoužívame jmené prostory, takže null
), kvalifikované jméno kořenového elementu a instance třídy DocumentType
popisující typ našeho dokumentu (opět, DTD nepoužíváme, takže null
).
public PhoneBookTableModel(java.lang.String uri) throws PhoneBookException { try { DocumentBuilder builder=DocumentBuilderFactory.newInstance().newDocumentBuilder(); doc = builder.parse(uri); } catch (java.lang.Exception ex) { // Neco je spatne, vicemene nas nezajima co throw new PhoneBookException("Cannot load document: "+ex.toString()); } checkDocumentStructure(); }
Opět získáme instanci třídy DocumentBuilder
a pomocí její metody parse() načteme dokument. Nakonec zavoláme metodu checkDocumentStructure(), jež zkontroluje že kořenový element je opravdu <phone-book>
a spočíta počet položek:
private void checkDocumentStructure() throws PhoneBookException{ if (!doc.getDocumentElement().getNodeName().equals("phone-book")) throw new PhoneBookException("Wrong document: "+doc.getDocumentElement().getNodeName()); rowCount=doc.getDocumentElement().getElementsByTagName("person").getLength(); fireTableStructureChanged(); }
Během vytváření instance třídy DocumentBuilder
by mohlo dojít k nejrůznějším výjimkám, náš příklad je ovšem tak jednoduchý že jakákoli výjimka může znamenat pouze to, že na našem počítači není k dispozici žadný XML parser. Při načítání dokumentu mohou též vzniknout nejrůznější výjimky, většinou se vztahují k IO chybám (neexistující soubor) nebo chybám v dokumentu (chyba syntaxe, chyba při překódování do Unicode, dokument není správně strukturován, dokument vůbec není XML...), proto tuto výjimku obalíme do naší třídy PhoneBookException
a vyhodíme dál, v hlavní třídě naší aplikace se uživateli zobrazí jako okno s chybovým hlášením. Poslední variantou je, že výše uvedená metoda checkDocumentStructure() zjistí, že kořenový element není <phone-book>
, a tudíž také vyvolá výjimku.
synchronized public void saveToFile(java.io.File file) throws PhoneBookException { try { javax.xml.transform.TransformerFactory.newInstance().newTransformer(). transform(new javax.xml.transform.dom.DOMSource(doc), new javax.xml. transform.stream.StreamResult(file)); } catch (Throwable ex) { // Neco je spatne, vicemene nas nezajima co throw new PhoneBookException("Cannot save document"); } }
Dokument ukládáme přesně způsobem popsaným v prvním díle. Prostřednictvím metody newTransformer() tovární třídy TransformerFactory
vytvoříme instanci třídy Transformer
, v tomto případě nemá tato instance asociovanou žádnou šablonu, a proto pouze kopíruje vstup na výstup. Poté zavoláme metodu transform(), jejímiž parametry jsou zdroj a výsledek transformace. Jako zdroj použijeme instanci třídy DOMSource
pracující nad naším dokumentem doc
. A výsledkem bude instance třídy StreamResult
obalující soubor, do kterého chceme ukládat.
Příště se podíváme, jak s naším dokumentem doc
dále pracujeme, jak odpovídáme na dotazy třídy JTable
na hodnoty buněk, jak tyto hodnoty měníme, jak přidáváme, mažeme a měníme pořadí položek.