Architekturen für verteilte Internetdienste

Werbung
1 Überblick
■ XML-APIs für Java
■ SAX
Architekturen für
verteilte Internetdienste
■ DOM
■ Java: JDOM, dom4j, StAX
■ Validierendes Parsen
Übung 1: XML + APIs
[email protected]
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
2 XML-APIs für Java
3 Simple API for XML (SAX)
■ Konzept
■ Event-Driven Parsing
◆ Herstellerunabhängige Schnittstelle
■ Push von „Elementen“ des Dokuments an Handler
◆ Beliebige Implementierung
■ Zustandsloser Stream ohne Navigationsmöglichkeit
• Auswahl zur Laufzeit: System Properties + Factories
■ Vorgehen
■ Packages: javax.xml, org.xml, org.w3c
◆ SAXParserFactory erzeugt SAXParser (package javax.xml.parsers)
■ DOM-Parser: Baum von Elementen des Dokuments
◆ Dessen SAXReader ruft diverse Handler auf
◆ Sprachunabhängiges Document Object Model
◆ ContentHandler, ErrorHandler, DTDHandler, EntityResolver, ...
◆ Eigenen von DefaultHandler ableiten und ergänzen
■ SAX-Parser: Stream Pushing
◆ Simple API for XML
■ StAX-Parser: Stream Pulling
■ JDOM-Parser: DOM à la Java
■ Aktueller Parser im Java SDK: Apache-Xerces
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
1.1
1.2
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
3 Simple API for XML (SAX)
3 Simple API for XML (SAX)
■ Programmierung
■ Implementierung eines eigenen Handlers
◆ DefaultHandler ableiten
public
{
void
void
void
◆ Ggf. weitere Handler für CDATA, DTD-Elemente, ...
◆ Factory, Parser initialisieren und starten
class MyHandler extends DefaultHandler
startDocument() throws SAXException {...}
endDocument () ...
startElement (String namespaceURI,
String sName, String qName,
Attributes attrs) ...
void endElement
(String namespaceURI,
String sName, String qName) ...
void characters
(char[] buf, int offset, int len) ...
...
void ignorableWhitespace (char[] buf, int offset, int len) ...
void processingInstruction(String target, String data) ...
void setDocumentLocator
(Locator l) ...
...
void warning (SAXParseException e) ...
void error
(SAXParseException e) ...
◆ Ggf. validierendes Parsen, Namespace-Awareness konfigurieren
}
1.3
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
1.4
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
4 Document Object Model (DOM)
4 Document Object Model (DOM)
■ Parsing läuft automatisch durch und erzeugt DOM-Baum
■ Vorgehen
◆ DocumentBuilderFactory erzeugt DocumentBuilder
■ Navigation auf Dokumentbaum von mäßig getypten Knoten
◆ Document per newDocument() oder Parsing erzeugen
■ Sprachunabhängige API
◆ Root-Element: Document.getDocumentElement()
◆ Alles ist ein Knoten (Element, Attribut, Text, ...)
◆ Node-API mit nodeValue(), nodeType(), nodeName()
◆ Schwerfällig
◆ Nervig: getNodeType()==Node.ELEMENT NODE
Beispiel: <e>bla<e>
Node child = data.getFirstChild();
while(child!=null) {
if (child.getNodeType() == Node.ELEMENT_NODE) {
Element e = (Element) child; ...
}
else ...
child = child.getNextSibling();
}
◆ <e>: nodeType()=”e”, nodeValue()=null
◆ bla: nodeType()=”#text”, nodeValue()=”bla”
◆ getElementsByTagName() ist transitiv, nicht auf direkte Subknoten beschränkt
◆ getChildNodes() liefert alle Subknoten, nicht nur Subelemente
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
1.5
1.6
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
4 Document Object Model (DOM)
4 Document Object Model (DOM)
■ Parsen
■ Wichtige Methoden (Auswahl)
◆ org.w3c.dom.Node
DocumentBuilderFactory factory;
DocumentBuilder
builder;
Document
doc;
• appendChild, removeChild, getTextContent, getParentNode,
getOwnerDocument, getNodeName/Type/Value, get/hasAttributes,
getFirst/LastChild, getNextSibling, getChildNodes
factory = DocumentBuilderFactory.newInstance();
◆ org.w3c.dom.Document
builder = factory.newDocumentBuilder();
builder.setErrorHandler(new org.xml.sax.ErrorHandler() {...});
doc
• getDocumentElement, createAttribute, createElement, createTextNode,
getElementsByTagName
◆ Ableitungen: org.w3c.dom.Element, .Attr, .Comment, .Text, ...
= builder.parse( new File("data.xml") );
1.7
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
1.8
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5 Java: JDOM, dom4j, StAX
5 Java: JDOM, dom4j, StAX
■ JDOM
■ JDOM Beispiel
◆ Java-OOP DOM-Zugriff
◆ Packages org.jdom.** von http://www.jdom.org
SAXBuilder builder = new SAXBuilder(true);
◆ Nutzt SAX/DOM-Parser, z.B. via org.jdom.input.SAXBuilder
Document doc = builder.build("data.xml");
Element root = doc.getRootElement();
◆ Konkrete Klassen anstatt Interfaces
◆ Analoge Methoden zum Manipulieren, Validieren
println("Element: "+root.getName());
for (Attribute a: root.getAttributes())
println("- Attribute "+a.getName()+"="+a.getValue());
for (Element e: root.getChildren())
println("- Element
"+e.getName());
◆ JSR-102 javax.xml.tree
■ Alternative dom4j
◆ Schneller/kleiner
◆ Schnelle Traversierung großer Dokumente
◆ Auf Interfaces aufbauende Implementierung
◆ XPath-Integration
1.9
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
1.10
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5 Java: JDOM, dom4j, StAX
6 Validierendes Parsen
■ XML-Pull-Parsing: JSR-173 javax.xml.stream
■ ... am Beispiel von SAX:
String VALIDATE =
"http://xml.org/sax/features/validation";
String VAL_XSD =
"http://apache.org/xml/features/validation/schema";
URL u = new URL("data.xml");
InputStream in = u.openStream();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader parser = factory.createXMLStreamReader(in);
for (int event = parser.next();
event != XMLStreamConstants.END_DOCUMENT;
event = parser.next()) {
switch (event) {
case XMLStreamConstants.START_ELEMENT:
case XMLStreamConstants.END_ELEMENT:
parser.getLocalName(); break;
case XMLStreamConstants.CDATA:
case XMLStreamConstants.CHARACTERS:
parser.getText(); break;
}
}
parser.close();
DefaultHandler hr = new Handler();
XMLReader xr = XMLReaderFactory.createXMLReader();
xr.setFeature(VALIDATE, true);
xr.setFeature(VAL_XSD, true);
xr.setContentHandler(hr);
xr.setErrorHandler(hr);
FileReader r = new FileReader(filepath);
xr.parse(new InputSource(r));
1.11
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
7 Aufgabe
■ Implementierung eines einfachen SAX-Parsers
◆ Verwenden des DefaultHandler
◆ Ausgabe der Namespaces
◆ Ausgabe Präfixe
◆ Ausgabe Events
■ Was ist ein DTDHandler / EntityResolver
■ Unterschied DefaultHandler vs. DefaultHandler2
■ Implementierung eines einfachen DOM-Parsers
◆ Ausgabe der Knotentypen
◆ Ausgabe der Attribute
■ Welchen Parser in welcher Situation?
1.13
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
1.12
© 2006, Holger Schmidt, Verteilte Systeme, Univ. Ulm, [u1.fm, 2006-05-05 09.37] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
Herunterladen