Heutige Vorlesung Welche XML-Parser gibt es? Was sind ihre Vor- und Nachteile? Was sind Schema-Übersetzer? XML-Parser © Klaus Schild, 2004 1 Grundlegende Architektur © Klaus Schild, 2004 2 Kategorien von Parser PullPull- vs. PushPush-Parser Wer hat Kontrolle über das Parsen: die Anwendung oder der Parser? Zeichenkette XMLDokument Anwendung Serialisierer Parser EinschrittEinschritt- vs. MehrschrittMehrschritt-Parser (one-step vs. multi-step parsing) standardisierte APIs Wird das XML-Dokument in einem Schritt vollständig geparst oder Schritt für Schritt? Möglichst standardisierte APIs verwenden! Parser: Parser Analysiert XML-Dokument und erstellt Parse-Baum mit Tags, Text-Inhalten und Attribut-Wert-Paaren als Knoten. Beachte: Kategorien unabhängig voneinander, können kombiniert werden Serialisierer: Serialisierer Generiert aus bestimmter Datenstruktur ein XMLDokument. © Klaus Schild, 2004 3 PullPull-Parser © Klaus Schild, 2004 4 PushPush-Parser nächste Einheit? Pull-Parser geparste Einheit Anwendung Push-Parser geparste Einheit Anwendung Anwendung hat Kontrolle über das Parsen. Parser hat Kontrolle über das Parsen. Analyse der nächsten syntaktischen Einheit muss aktiv angefordert werden. Sobald der Parser eine syntaktische Einheit analysiert hat, übergibt er die entsprechende Analyse. Beachte: „Pull” bezieht sich auf die Perspektive der Anwendung. Beachte: „Push” bezieht sich wiederum auf die Perspektive der Anwendung. © Klaus Schild, 2004 5 © Klaus Schild, 2004 6 1 XMLXML-Parser One-step Multi-step JAXP DOM Pull SAX-Parser Push SAX JAXP: JAXP Java API for XML Processing DOM: DOM Document Object Model SAX: SAX Simple API for XML © Klaus Schild, 2004 7 Simple API for XML (SAX) © Klaus Schild, 2004 8 Ereignisbasiertes Parsen Mehrschritt-Push-Parser für XML standardisiertes API SAX-Parser ursprünglich nur Java-API, inzwischen werden aber auch viele andere Sprachen unterstützt Ereignis: neue syntaktische Einheit geparst einmaliges Anstoßen des Parsens kein W3C-Standard, sondern de facto Standard Î http://www.saxproject.org/ Event Handler Anwendung © Klaus Schild, 2004 9 Beispiel <priceList> <priceList> <coffee> <coffee> <name> <name> MochaJava Java Mocha </name> </name> <price> <price> 11.95 11.95 </price> </price> </coffee> </coffee> </priceList> </priceList> 10 CallbackCallback-Methoden Parser ruft startElement(…,priceList,…) auf. Parser ruft startElement(…,coffee,…) auf. Parser ruft startElement(…,name,…) auf. Parser ruft characters("Mocha Java",…) auf. Parser ruft endElement(…,name,..) auf. Parser ruft startElement(…,price,…) auf. Parser ruft characters("11.95",…) auf. Parser ruft endElement(…,price,…) auf. Parser ruft endElement(…,coffee,…) auf. Parser ruft endElement(…,priceList,…) auf. Ereignisfluss: Ereignisfluss Sobald Einheit geparst wurde, wird Anwendung benachrichtigt. CallbackCallback-Methoden: Methoden Methoden des Event-Handlers (also der Anwendung), die vom Parser aufgerufen werden. für jede syntaktische Einheit in XML eigene CallbackMethode: startElement endElement characters DefaultHandler: DefaultHandler Standard-Implementierung der CallbackMethoden, tun jeweils nichts. Standard-Implementierungen können aber überschrieben werden. Beachte: Es wird kein Parse-Baum aufgebaut! © Klaus Schild, 2004 © Klaus Schild, 2004 11 © Klaus Schild, 2004 12 2 Beispiel Wie bekomme ich einen SAXSAX-Parser? Parser? SAXParserFactoryfactory factory==SAXParserFactory.newInstance(); SAXParserFactory.newInstance(); SAXParserFactory <priceList> <priceList> <coffee> <coffee> <<name> name> name> MochaJava Java Mocha </name> </name name> > </ <<price> price> price> 11.95 11.95 </price> </price price> > </ </coffee> </coffee> </priceList> </priceList> Aufgabe: Gib den Preis von Mocha Java aus! Hierfür benötigen wir zwei Dinge: liefert eine SAXParserFactory SAXParsersaxParser saxParser==factory.newSAXParser(); factory.newSAXParser(); SAXParser liefert einen SAXParser saxParser.parse("priceList.xml",handler); handler); saxParser.parse("priceList.xml", 1. einen SAX-Parser 2. passende CallbackMethoden stößt SAX-Parser an priceList.xml: zu parsende Datei, kann auch URL oder Stream sein handler: Instanz von DefaultHandler, implementiert Callback-Funktionen © Klaus Schild, 2004 13 © Klaus Schild, 2004 14 Exkurs: Factory Method Wie sehen die CallbackCallback-Methoden aus? Entwurfsmuster aus „Design Patterns“ von Gamma, Helm, Johnson, Vlissides (1995) <priceList> <priceList> <coffee> <coffee> <<name> name> name> liefert ein Objekt MochaJava Java Mocha </name> </name> <<price> price> price> 11.95 11.95 </price> </price> </coffee> </coffee> </priceList> </priceList> Objekt ist Instanz einer abstrakten Klasse oder einem Interface. wird von mehreren Klassen implementiert Beispiel: Iterator i = list.iterator(); Beispiel: SAXParser saxParser = factory.newSAXParser(); Aufgabe: Gib den Preis von Mocha Java aus! © Klaus Schild, 2004 15 Die CallbackCallback-Methoden in Java Start startElement = name? inName characters = Mocha Java? inMochaJava startElement = price? inPrice characters = s? print(s) © Klaus Schild, 2004 16 Auf <name> name> warten publicvoid voidstartElement(..., startElement(..., StringelementName, elementName, ...){{ public (..., String , ...) startElement elementName (elementName.equals("name")){ inName inName==true; true; }} ifif(elementName.equals("name")){ elseifif(elementName.equals("price") (elementName.equals("price")&& &&inMochaJava inMochaJava){ ){ else inPrice==true; true; inPrice inName==false; false; }}}} inName publicvoid voidstartElement(..., startElement(...,String StringelementName, elementName,...){ ...){ public startElement inName==true; true; ifif((elementName.equals("name")){ elementName.equals("name")){ ; }} elementName.equals("name")){ inName true elseifif(elementName.equals("price") (elementName.equals("price")&& &&inMochaJava inMochaJava){ ){ else inPrice==true; true; inPrice <name>Mocha Java</name> <name name>Mocha Java</name> inName==false; false; }}}} inName <price>11.95</price> <price>11.95</price> publicvoid voidcharacters(char characters(char[][]buf, buf, intoffset, offset, intlen) len) public , int , int ) {{ buf offset len Stringss==new newString(buf, String(buf, offset, len); String , offset, , len); ); String(buf offset len (inName&& &&s.equals("Mocha s.equals("MochaJava")) Java")){{ ifif(inName inMochaJava==true; true; inMochaJava inName==false; false; }} inName elseifif(inPrice) (inPrice){{ else System.out.println("Theprice priceof ofMocha MochaJava Javais: is:""++s); s); System.out.println("The inMochaJava==false; false; inMochaJava inPrice==false; false; }} }} inPrice publicvoid voidcharacters(char characters(char[][]buf, buf,int intoffset, offset,int intlen) len){{ public Stringss==new newString(buf, String(buf,offset, offset,len); len); String (inName&& &&s.equals("Mocha s.equals("MochaJava")) Java")){{ ifif(inName inMochaJava==true; true; inMochaJava inName==false; false; }} inName elseifif(inPrice) (inPrice){{ else System.out.println("Theprice priceof ofMocha MochaJava Javais: is:""++s); s); System.out.println("The inMochaJava==false; false; inMochaJava inPrice==false; false; }} }} inPrice © Klaus Schild, 2004 17 © Klaus Schild, 2004 Start inName 18 3 Auf "Mocha Java" warten Auf <price> price> warten publicvoid voidstartElement(..., startElement(...,String StringelementName, elementName,...){ ...){ public (elementName.equals("name")){ inName inName==true; true; }} ifif(elementName.equals("name")){ elseifif(elementName.equals("price") (elementName.equals("price")&& &&inMochaJava inMochaJava){ ){ else inPrice==true; true; inPrice <name>Mocha Java</name> <name>Mocha Mocha Java</name> Java inName==false; false; }}}} inName <price>11.95</price> <price>11.95</price> publicvoid voidstartElement(..., startElement(...,String StringelementName, elementName,...){ ...){ public startElemen (elementName.equals("name")){ inName inName==true; true; }} ifif(elementName.equals("name")){ elseifif((elementName.equals("price") &&inMochaJava inMochaJava){){ else elementName.equals("price") elementName.equals("price") && inPrice==true; true; inPrice ; true <name>MochaJava</name> Java</name> <name>Mocha inName==false; false; inName ; }}}} false <price>11.95</price> <price price>11.95</price> publicvoid voidcharacters(char characters(char[][]buf, buf,int intoffset, offset,int intlen) len){{ public characters Stringss==new newString(buf, String(buf,offset, offset,len); len); String &&s.equals("Mocha s.equals("MochaJava")) Java")){{ ifif((inName inName && inMochaJava==true; true; inMochaJava ; true inName==false; false; inName ; }} false elseifif(inPrice) (inPrice){{ else System.out.println("Theprice priceof ofMocha MochaJava Javais: is:""++s); s); System.out.println("The inMochaJava==false; false; inMochaJava inPrice==false; false; }} }} inPrice publicvoid voidcharacters(char characters(char[][]buf, buf,int intoffset, offset,int intlen) len){{ public Stringss==new newString(buf, String(buf,offset, offset,len); len); String (inName&& &&s.equals("Mocha s.equals("MochaJava")) Java")){{ ifif(inName inMochaJava==true; true; inMochaJava inName==false; false; }} inName elseifif(inPrice) (inPrice){{ else System.out.println("Theprice priceof ofMocha MochaJava Javais: is:""++s); s); System.out.println("The inMochaJava==false; false; inMochaJava inPrice==false; false; }} }} inPrice Start inName inMochaJava © Klaus Schild, 2004 19 Den Preis ausgeben publicvoid voidcharacters(char characters(char[][]buf, buf,int intoffset, offset,int intlen) len){{ public characters Stringss==new newString(buf, String(buf,offset, offset,len); len); String (inName&& &&s.equals("Mocha s.equals("MochaJava")) Java")){{ ifif(inName inMochaJava==true; true; inMochaJava inName==false; false; }} inName elseifif((inPrice) else inPrice) inPrice) {{ System.out.println("Theprice priceof ofMocha MochaJava Javais: s); System.out.println("The : ""++s); isis: inMochaJava==false; false; inMochaJava ; false inPrice==false; false; inPrice ; }} }} false Start inPrice 21 Fehlerbehandlung <price>11.95</price> <price>11.95</price> Kommt stattdessen name-Element, wird aktueller Zustand nicht verändert. © Klaus Schild, 2004 20 <priceList> <priceList> <coffee> <coffee> <<name> name> name> MochaJava Java Mocha </name> </name> <<name> name> name> MSJava Java MS </name> </name> <<price> price> price> 11.95 11.95 </price> </price> </coffee> </coffee> </priceList> </priceList> Start startElement = name? inName characters = Mocha Java? inMochaJava startElement = price? inPrice characters = s? print(s) © Klaus Schild, 2004 22 Fehlerbehandlung publicvoid voidstartElement(..., startElement(...,String StringelementName, elementName,...){ ...){ public (elementName.equals("name")){ inName inName==true; true; }} ifif(elementName.equals("name")){ elseifif((elementName.equals("price") &&inMochaJava inMochaJava){){ else elementName.equals("price") elementName.equals("price") && inPrice==true; true; inPrice ; true <name>MochaJava</name> Java</name> <name>Mocha inName==false; false; inName ; }}}} false <name>MSJava</name> Java</name> <name>MS Dadurch wird Preis von MS Java ausgegeben! inPrice © Klaus Schild, 2004 print(s) © Klaus Schild, 2004 Kommt danach price-Element, wird der aktueller Zustand inPrice. inMochaJava Fehlerbehandlung publicvoid voidstartElement(..., startElement(...,String StringelementName, elementName,...){ ...){ public (elementName.equals("name")){ inName inName==true; true; }} ifif(elementName.equals("name")){ elseifif(elementName.equals("price") (elementName.equals("price")&& &&inMochaJava inMochaJava){ ){ else inPrice==true; true; inPrice <name>Mocha Java</name> <name>Mocha Java</name> inName==false; false; }}}} inName <price>11.95</price> <price>11.95 11.95</price> inMochaJava erwartet price-Element inName SAX-Parser überprüft immer Wohlgeformtheit eines XML-Dokumentes. kann aber auch die Zulässigkeit bzgl. einer DTD oder eines Schema überprüfen Syntax- und Strukturfehler fängt bereits der SAX-Parser ab. inName Callback-Methoden können von einem wohlgeformten und zulässigen Dokument ausgehen. inMochaJava inPrice 23 © Klaus Schild, 2004 24 4 VorVor- und Nachteile von SAX Zusätzliche Schicht zum Datenzugriff Anwendung + sehr effizient, auch bei großen XML-Dokumenten – Kontext (Parse-Baum) muss von Anwendung selbst verwaltet werden. Datenzugriff Datenzugriff SAX SAX – abstrahiert nicht von XML-Syntax startElement characters – nur Parsen möglich, keine Modifikation oder Erstellung von XML-Dokumenten Anwendungslogik getPriceList() Immer Anwendungslogik durch zusätliche Schicht von dem Datenzugriff trennen (nicht nur bei SAX). Z.B. könnte getPriceList() eine Liste von Ware-PreisPaaren liefern. sollte nicht nur von SAX-APIs, sondern auch von der XML-Syntax abstrahieren © Klaus Schild, 2004 25 © Klaus Schild, 2004 26 Document Object Model (DOM) XMLParser DOM-Parser DOM Anwendung W3C-Standard abstrakte Schnittstelle zum Zugreifen, Modifizieren und Erstellen von Parse-Bäumen unabhängig von Programmiersprachen nicht nur für XML-, sondern auch für HTML-Dokumente im Ergebnis ein Einschritt-Pull-Parser © Klaus Schild, 2004 27 DOMDOM-ParseParse-Bäume <?xmlversion="1.0" version="1.0"?> ?> <?xml <priceList> <priceList> <coffee> <coffee> <name>MochaJava</name> Java</name> <name>Mocha <price>11.95</price> <price>11.95</price> </coffee> </coffee> </priceList> </priceList> © Klaus Schild, 2004 DOMDOM-ParseParse-Bäume Document Node <?xmlversion="1.0" version="1.0"?> ?> <?xml Beachte: Text-Inhalte <priceList> <priceList> werden als eigene Knoten <coffee> <coffee> dargestellt. <name>MochaJava</name> Java</name> <name>Mocha <price>11.95</price> <price>11.95</price> Element Node: coffee </coffee> </coffee> </priceList> NodeList </priceList> NodeList Element Node: PriceList NodeList Element Node: coffee Element Node: name Beachte: priceList ≠ Dokument-Wurzel DOM führt virtuelle Dokument-Wurzel ein, um syntaktische Einheiten außerhalb von priceList (wie version="1.0") repräsentieren zu können. © Klaus Schild, 2004 28 29 © Klaus Schild, 2004 Element Node: price NodeList NodeList Text Node: Mocha Java Text Node: 11.95 30 5 Navigationsmodell Beispiel <priceList> <priceList> <coffee> <coffee> <<name> name> name> parentNode previousSibling MochaJava Java Mocha </name> </name name> > </ <<price> price> price> 11.95 11.95 </price> </price price> > </ </coffee> </coffee> </priceList> </priceList> nextSibling Node childNodes firstChild lastChild © Klaus Schild, 2004 31 Aufgabe: Gib des Preis von Mocha Java aus! Hierfür benötigen wir zwei Dinge: 1. einen DOM-Parser 2. eine passende Zugriffsmethode © Klaus Schild, 2004 32 Wie bekomme ich einen DOMDOM-Parser? Parser? Wie sehen die Zugriffsmethoden aus? DocumentBuilderFactoryfactory factory== DocumentBuilderFactory.newInstance(); DocumentBuilderFactory.newInstance(); DocumentBuilderFactory NodeListcoffeeNodes coffeeNodes==document.getElementsByTagName("coffee"); document.getElementsByTagName("coffee"); NodeList "); document.getElementsByTagName("coffee for(int (inti=0; i=0;ii<<coffeeNodes.getLength(); coffeeNodes.getLength();i++) i++){{ for liefert DocumentBuilderFactory DocumentBuilderbuilder builder==factory.newDocumentBuilder(); factory.newDocumentBuilder(); DocumentBuilder thisCoffeeNode==coffeeNodes.item(i); coffeeNodes.item(i); thisCoffeeNode NodethisNameNode thisNameNode==thisCoffeeNode.getFirstChild(); thisCoffeeNode.getFirstChild(); Node (); thisCoffeeNode.getFirstChild Stringdata data==thisNameNode.getFirstChild().getNodeValue(); thisNameNode.getFirstChild().getNodeValue(); String (); thisNameNode.getFirstChild().getNodeValue (data.equals("MochaJava")) Java")){{ ifif(data.equals("Mocha liefert DOM-Parser NodethisPriceNode thisPriceNode==thisNameNode.getNextSibling(); thisNameNode.getNextSibling(); Node (); thisNameNode.getNextSibling Stringprice price== thisPriceNode.getFirstChild().getNodeValue(); thisPriceNode.getFirstChild().getNodeValue(); String (); thisPriceNode.getFirstChild().getNodeValue Documentdocument document==builder.parse("priceList.xml"); builder.parse("priceList.xml"); Document break;}}}} break; DOM-Parser hat Methode parse(). Java-Programm, das das DOMDOMJava-Programm, Methoden benutzt benutzt Methoden liefert DOM-Parse-Baum © Klaus Schild, 2004 33 © Klaus Schild, 2004 34 Gib mir die Liste aller coffeecoffee-Elemente! Elemente! Betrachte alle Elemente der coffeecoffee-Liste! Liste! NodeListcoffeeNodes coffeeNodes==document.getElementsByTagName("coffee"); document.getElementsByTagName("coffee"); NodeList "); document.getElementsByTagName("coffee NodeListcoffeeNodes coffeeNodes==document.getElementsByTagName("coffee"); document.getElementsByTagName("coffee"); NodeList for((int i=0;ii<<coffeeNodes.getLength(); coffeeNodes.getLength(); i++){{ for int i=0; (); i++) coffeeNodes.getLength thisCoffeeNode==coffeeNodes.item(i); coffeeNodes.item(i); thisCoffeeNode ); coffeeNodes.item(i <?xmlversion="1.0" version="1.0"?> ?> … <?xml … <priceList> <priceList> } } <coffee> <coffee> <name>MochaJava</name> Java</name> <name>Mocha <price>11.95</price> <price>11.95</price> </coffee> </coffee> coffeeNodes.item(0) </priceList> </priceList> getElementsByTagName: direkter Zugriff auf Elemente über ihren Namen egal, wo Elemente stehen Resultat ist immer eine NodeList. © Klaus Schild, 2004 <?xmlversion="1.0" version="1.0"?> ?> <?xml <priceList> <priceList> <coffee> <coffee> <name>MochaJava</name> Java</name> <name>Mocha <price>11.95</price> <price>11.95</price> </coffee> </coffee> </priceList> </priceList> 35 © Klaus Schild, 2004 36 6 Gib mir erstes KindKind-Element von coffee! coffee! Gib mir den Inhalt von name! name! NodeListcoffeeNodes coffeeNodes==document.getElementsByTagName("coffee"); document.getElementsByTagName("coffee"); NodeList for(int (inti=0; i=0;ii<<coffeeNodes.getLength(); coffeeNodes.getLength();i++) i++){{ for NodeListcoffeeNodes coffeeNodes==document.getElementsByTagName("coffee"); document.getElementsByTagName("coffee"); NodeList for(int (inti=0; i=0;ii<<coffeeNodes.getLength(); coffeeNodes.getLength();i++) i++){{ for thisCoffeeNode==coffeeNodes.item(i); coffeeNodes.item(i); thisCoffeeNode NodethisNameNode thisNameNode==thisCoffeeNode.getFirstChild(); thisCoffeeNode.getFirstChild(); Node (); thisCoffeeNode.getFirstChild thisCoffeeNode==coffeeNodes.item(i); coffeeNodes.item(i); thisCoffeeNode NodethisNameNode thisNameNode==thisCoffeeNode.getFirstChild(); thisCoffeeNode.getFirstChild(); Node Stringdata data==thisNameNode.getFirstChild().getNodeValue(); thisNameNode.getFirstChild().getNodeValue(); String (data.equals("MochaJava")) Java")){{ ifif(data.equals("Mocha NodethisPriceNode thisPriceNode==thisCoffeeNode.getNextSibling(); thisCoffeeNode.getNextSibling(); Node <?xmlversion="1.0" version="1.0"?> ?> <?xml Stringprice price== thisPriceNode.getFirstChild().getNodeValue(); thisPriceNode.getFirstChild().getNodeValue(); String <priceList> <priceList> break;}}}} break; <coffee> <coffee> <name>MochaJava</name> Java</name> <name>Mocha firstChild <price>11.95</price> <price>11.95</price> </coffee> </coffee> </priceList> </priceList> © Klaus Schild, 2004 37 Stringdata data==thisNameNode.getFirstChild().getNodeValue(); thisNameNode.getFirstChild().getNodeValue(); String (); thisNameNode.getFirstChild().getNodeValue (data.equals("MochaJava")) Java")){{ ifif(data.equals("Mocha NodethisPriceNode thisPriceNode==thisCoffeeNode.getNextSibling(); thisCoffeeNode.getNextSibling(); Node <?xmlversion="1.0" version="1.0"?> ?> <?xml Stringprice price== thisPriceNode.getFirstChild().getNodeValue(); thisPriceNode.getFirstChild().getNodeValue(); String <priceList> <priceList> firstChild break; } } break; } } <coffee> <coffee> <name>MochaJava</name> Java</name> <name>Mocha Beachte: getFirstChild() liefert <price>11.95</price> <price>11.95</price> </coffee> Text-Knoten, nicht dessen </coffee> </priceList> Inhalt „Mocha Java“! </priceList> © Klaus Schild, 2004 Gib mir das nächste KindKind-Element! Gib mir den Inhalt von price! price! NodeListcoffeeNodes coffeeNodes==document.getElementsByTagName("coffee"); document.getElementsByTagName("coffee"); NodeList for(int (inti=0; i=0;ii<<coffeeNodes.getLength(); coffeeNodes.getLength();i++) i++){{ for <?xmlversion="1.0" version="1.0"?> ?> <?xml NodeListcoffeeNodes coffeeNodes==document.getElementsByTagName("coffee"); document.getElementsByTagName("coffee"); NodeList <priceList> <priceList> for (int i=0; i < coffeeNodes.getLength(); i++) { for (int i=0; i < coffeeNodes.getLength(); i++)<coffee> { <coffee> thisCoffeeNode==coffeeNodes.item(i); coffeeNodes.item(i); thisCoffeeNode <name>MochaJava</name> Java</name> <name>Mocha NodethisNameNode thisNameNode==thisCoffeeNode.getFirstChild(); thisCoffeeNode.getFirstChild(); <price>11.95</price> Node <price>11.95</price> </coffee> Stringdata data==thisNameNode.getFirstChild().getNodeValue(); thisNameNode.getFirstChild().getNodeValue(); </coffee> String firstChild </priceList> </priceList> if (data.equals("Mocha Java")) { if (data.equals("Mocha Java")) { NodethisPriceNode thisPriceNode==thisNameNode.getNextSibling(); thisNameNode.getNextSibling(); Node thisCoffeeNode==coffeeNodes.item(i); coffeeNodes.item(i); thisCoffeeNode NodethisNameNode thisNameNode==thisCoffeeNode.getFirstChild(); thisCoffeeNode.getFirstChild(); Node Stringdata data==thisNameNode.getFirstChild().getNodeValue(); thisNameNode.getFirstChild().getNodeValue(); String Java")){{ ifif((data.equals("Mocha data.equals("Mocha Java")) NodethisPriceNode thisPriceNode==thisNameNode.getNextSibling(); thisNameNode.getNextSibling(); Node (); thisNameNode.getNextSibling Stringprice price== thisPriceNode.getFirstChild().getNodeValue(); thisPriceNode.getFirstChild().getNodeValue(); <?xmlversion="1.0" version="1.0"?> ?> String <?xml <priceList> break;}}}} <priceList> break; <coffee> <coffee> <name>MochaJava</name> Java</name> <name>Mocha nextSibling <price>11.95</price> <price>11.95</price> </coffee> </coffee> </priceList> </priceList> © Klaus Schild, 2004 39 VorVor- und Nachteile von DOM Stringprice price== thisPriceNode.getFirstChild().getNodeValue(); thisPriceNode.getFirstChild().getNodeValue(); String (); thisPriceNode.getFirstChild().getNodeValue break;}}}} break; © Klaus Schild, 2004 40 SAX oder DOM? SAX + Kontext (Parse-Baum) muss nicht von Anwendung verwaltet werden. geeignet, um gezielt bestimmte Teile von XMLDokumenten herauszufiltern, ohne zu einem späteren Zeitpunkt andere Teile des Dokumentes zu benötigen + direkter Zugriff auf Elemente und Attribute über ihre Namen DOM + nicht nur Parsen, sondern auch Modifikation und Erstellung von XML-Dokumenten geeignet, um auf unterschiedliche Teile eines XMLDokumentes zu verschiedenen Zeitpunkten zuzugreifen – speicherintensiv © Klaus Schild, 2004 38 Erstellen und Modifizieren von XML-Dokumenten 41 © Klaus Schild, 2004 42 7 SchemaSchema-Übersetzer Datenabstraktion XMLSchema Schema-Übersetzer Übersetzen Va Instanz XMLDokument lid ie re n JavaKlassen Instanzen Deserialisieren Serialisieren JavaObjekte Java Architecture for XML Binding (JAXB JAXB) © Klaus Schild, 2004 43 Beispiel Klassen/Methoden werden generiert. Zweck: Schnittstelle, die von XML-Syntax abstrahiert. Lesen, Modifizieren und Erstellen von XML-Dokumenten möglich. © Klaus Schild, 2004 44 Warum noch XML lernen? <priceList> <priceList> <coffee> <coffee> <name>MochaJava</name> Java</name> <name>Mocha <price>11.95</price> <price>11.95</price> </coffee> </coffee> </priceList> </priceList> Schema-Übersetzer: XML-Schema kann in Java- oder C#-Klassen übersetzt werden. PriceList-Schema Hiermit können XML-Dokumente gelesen, modifiziert und erstellt werden, ohne dass XML sichtbar ist. JAXB Warum sich sich also also noch noch mit mit XML XML und und XMLXMLWarum Schemata beschäftigen? beschäftigen? Schemata publicinterface interfacePriceList PriceList{{ public java.util.ListgetCoffee(); getCoffee(); java.util.List publicinterface interfaceCoffeeType CoffeeType{{ public StringgetName(); getName(); String voidsetName(String setName(Stringvalue) value) void java.math.BigDecimalgetPrice(); getPrice(); java.math.BigDecimal voidsetPrice(java.math.BigDecimal setPrice(java.math.BigDecimalvalue) value)}}}} void © Klaus Schild, 2004 45 Typisches EE-BusinessBusiness-Projekt © Klaus Schild, 2004 46 Typisches EE-BusinessBusiness-Projekt: Phase I Welche Geschäftsdaten sollen ausgetauscht werden? Gibt es bereits einen passenden Branchenstandard? Zulieferer Wie sollen diese Geschäftsdaten in XML repräsentiert werden? Gibt es bereits einen geeigneten XML-Standard? Ziel: Branchenstandard in Form eines XML-Schemas Software-Architekten entwickeln entwickeln gemeinsam gemeinsam einen einen Software-Architekten XML-basierten Branchenstandard. Branchenstandard. XML-basierten Branchenvertreter wollen miteinander Geschäfte über das Internet machen. Sie müssen sich auf ein Austauschformat einigen. © Klaus Schild, 2004 47 © Klaus Schild, 2004 48 8 Typisches EE-BusinessBusiness-Projekt: Phase II Warum sich noch mit XML beschäftigen? Phase I: Software-Architekten beschäftigen sich intensiv mit entsprechender Branche, XML und XML-Schemata. XML Phase II: Programmierer können Schema-Übersetzer einsetzen und von XML abstrahieren. gegeben: Branchenstandard in Form eines XML-Schemas gemeinsames Verständnis der XML-Syntax Projektaufwand Aufgabe: Realisierung der Schnittstelle zwischen betriebsinterner Software und dem XML-Standard. PhaseII Phase Programmierer können können Schema-Übersetzer Schema-Übersetzer Programmierer einsetzen und und von von XML XML abstrahieren. abstrahieren. einsetzen © Klaus Schild, 2004 PhaseIIII Phase > 80% 49 © Klaus Schild, 2004 50 Wie geht es weiter? heutige Vorlesung ; Sax- und DOM-Parser ; Vor- und Nachteile von SAX und DOM ; Schema-Übersetzer nächste Woche Transformation von XML-Dokumenten mit XSLT © Klaus Schild, 2004 51 9