Heiner KückerXML Really Pull Parser |
|
Home Java-Seite Bit Packed Array ASM Improved heterogene Map, HMap Constraint Code Generator JSP WorkFlow PageFlow FlowControl Page Flow Engine Web Flow Engine Control_and_Command JSP_Spreadsheet Code-Generator für Option-Either-Stil in Java verbesserter Comparator Fluent-Interface Code-Generator auf Basis einer Grammatik Visitor mit Multidispatch for-Schleife mit yield-return Kognitions-Maschine semantisches Netz Domain Parser Codegenerator_für hierarchische Datenstrukturen Expression_Engine Formula_Parser Thread Preprocessor State Transition Engine AspectJ Java_Explorer DBF_Library Kalender_Applet SetGetGen BeanSetGet CheckPackage LineNumbers GradDms Excel-Export StringTokenizer JspDoc JspCheck JSP-Schulung Java Server Pages Struts Ascii-Tabellen- Layouter Ascii-Baum- Layouter Ascii-Art-Fluss- Diagramm- Parser AsciiArt AssignmentMatrix Layouter StringSerial Silbentrennung JDBC_Schlüssel- Generierung bidirektional/ unidirektional gelinkte Liste Java_Sitemap Generator XmlBuilder RangeMap StringFormatter VersionSafe XCopy JTextField CommandLine- ParamReader Bitmap-Grafik MultiMarkable- Buffered- InputStream JavaCache JdomUtil CollectionUtil XML Really Pull Parser Log-Filter Remote-Protokoll Sudoku-Generator Delegation statt Mehrfachvererbung Disjunct Interval Set WebCam_Demo Weiterentwicklung_Java Alaska-XBase++-Seite Projekte Philosophien Techniken Konzepte Sudoku Kontakt / Impressum Links SiteMap Letzte Aktualisierung: 15.06.2007 |
XML Really Pull Parser
Prototyp für einen XML-Parser, dessen Anwendugscode geanau die Struktur des XML-Dokumentes wiederspiegelt und keine Stack-Logik benötigt. XML really pull parser ---------------------- Neben den SAX- und DOM-XML-Parsern gibt es die sogenannten XML- Pull-Parser oder Streaming-Parser (StAX). Beim XML-Pull-Parser wird noch nach Cursor- oder Iterator- ähnlicher Verarbeitung unterschieden. Die meisten XML-Pull-Parser werden folgendermassen angewendet (Cursor-Verfahren): while( parser.hasNext() ) { int event = parser.next(); switch (event) { case XMLStreamConstants.END_DOCUMENT: System.out.println("END_DOCUMENT"); parser.close(); break; case XMLStreamConstants.START_ELEMENT: System.out.println("START_ELEMENT: " + parser.getLocalName() ); for( int i = 0; i < parser.getAttributeCount(); i++ ) System.out.println("Attribut: " + parser.getAttributeLocalName(i) + " Wert: " + parser.getAttributeValue(i)); break; case XMLStreamConstants.CHARACTERS: if( !parser.isWhiteSpace() ) System.out.println("CHARACTERS: " + parser.getText() ); break; case XMLStreamConstants.END_ELEMENT: System.out.println("END_ELEMENT: " + parser.getLocalName() ); break; default: break; } } Der Parser liefert beim Verarbeiten eine Reihe von Events. Es gibt verschiedene Eventtypen. START_DOCUMENT END_DOCUMENT START_ELEMENT END_ELEMENT CHARACTERS ENTITY_REFERENCE DTD COMMENT PROCESSING_INSTRUCTION Zum Verarbeiten verschachtelter Strukturen muss eine Stack-Logik aufgebaut werden. Ich verstehe unter Pull-Parsing etwas anderes. Für eine dreistufige Hierachie Haus -> Etage -> Wohnung verwendet man die Lösung, welche naheliegend ist, nämlich drei verschachtelte Schleifen (imperative Programmierung statt deklarativer oder eventgetriebener Programmierung). Deshalb habe ich hier mal einen anders aufgebauten XML-Parser, XML-Really-Pull-Parser, prototypisch implementiert. Er ist sehr untolerant bezüglich Fehlern oder Auslegungen im XML-Dokument, dafür kommt er aber mit sehr wenig Ressourcen aus, weil zum Beispiel unterschiedliche Reihenfolgen von Attributen nicht erlaubt sind. CDATA und innere DTD sind (noch) nicht implementiert, wie gesagt, es ist ein Prototyp. Das Parser-Anwendungsprogramm (das Programm welches das konkretete XML-Dokument abarbeitet und die XRPP-Lib benutzt) arbeitet sich vom Anfang an durch das XML-Dokument. Die Struktur des XML spiegelt sich in der Struktur des Codes wieder. Irgendwelche Stack-Strukturen sind nicht nötig. Als Stack dient der Java-Stack (lokale Variable, Parameter). Optionale Element oder Attribute kosten zusätzlichen Code und Performance. Andererseits werden bei einer stabilen XML-Struktur sehr wenig Ressourcen verbraucht. Beispiel für die Anwendung des XML Really Pull Parser ----------------------------------------------------- Links die XML-Datei 'rss.xml' dargestelt und rechts der entsprechende Java-Quelltext zum Parsen 'TestRssXml.java'. Wie man beim links rechts scrollen sehen kann, entspricht die Struktur des Java-Codes zum Parsen genau der Struktur des XML-Dokumentes. Dadurch ist das Programmieren eines XML-Parsers für ein bestimmtes festglegtes XML-Format sehr einfach. rss.xml | TestRssXml.java | <?xml version="1.0" encoding="ISO-8859-1"?> | parser.skipXmlDeclaration(); | <!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" | parser.skipDoctypeDeclaration(); "http://my.netscape.com/publish/formats/rss-0.91.dtd"> | <rss | parser.forceElementStart( "rss".getBytes() ); version="0.91"> | parser.getAttribute( "version".getBytes() ); | | parser.forceElementBody(); | { <channel> | parser.forceElementStart( "channel".getBytes() ); | parser.forceElementBody(); | { <title>mars</title> | parser.getElementBodyWithStartAndEndTag( "title".getBytes() ); <link>http://www.example.com/mars</link> | parser.getElementBodyWithStartAndEndTag( "link".getBytes() ); <description>Developer news from the MARS community</description> | parser.getElementBodyWithStartAndEndTag( "description".getBytes() ); <language>en-us</language> | parser.getElementBodyWithStartAndEndTag( "language".getBytes() ); <copyright>Copyright 2999-3001, MARS team.</copyright> | parser.getElementBodyWithStartAndEndTag( "copyright".getBytes() ); <managingEditor>editor@example.com</managingEditor> | parser.getElementBodyWithStartAndEndTag( "managingEditor".getBytes() ); <webMaster>webmaster@example.com</webMaster> | parser.getElementBodyWithStartAndEndTag( "webMaster".getBytes() ); | <image> | parser.forceElementStart( "image".getBytes() ); | parser.forceElementBody(); | { <title>mars</title> | parser.getElementBodyWithStartAndEndTag( "title".getBytes() ); <url>http://www.example.com/images/mynetscape3188.gif</url> | parser.getElementBodyWithStartAndEndTag( "url".getBytes() ); <link>http://www.example.com</link> | parser.getElementBodyWithStartAndEndTag( "link".getBytes() ); <width>88</width> | parser.getElementBodyWithStartAndEndTag( "width".getBytes() ); <height>31</height> | parser.getElementBodyWithStartAndEndTag( "height".getBytes() ); <description>News, and so on</description> | parser.getElementBodyWithStartAndEndTag( "description".getBytes() ); | } </image> | parser.forceElementStopNoEmpty( "image".getBytes() ); | <item> | while ( parser.isElementStart( "item".getBytes() ) ) | { | parser.forceElementStart( "item".getBytes() ); | parser.forceElementBody(); | | <title>MARS 1.0 Released</title> | parser.getElementBodyWithStartAndEndTag( "title".getBytes() ); <link>http://www.example.com/read?item=3322323</link> | parser.getElementBodyWithStartAndEndTag( "link".getBytes() ); <description>The MARS survival toolkit.</description> | parser.getElementBodyWithStartAndEndTag( "description".getBytes() ); | } </item> | parser.forceElementStopNoEmpty( "item".getBytes() ); | } | } </channel> | parser.forceElementStopNoEmpty( "channel".getBytes() ); | } </rss> | parser.forceElementStopNoEmpty( "rss".getBytes() ); | TODO Entwickeln eines Java-Programmes, zum Erzeugen des Parser-Codes aus einem Beispiel-XML, wobei mehrfach mögliche Elemente jeweils mindestens zweimal im Beispiel-XML notiert sein müssen, damit der Code-Generator erkennt, dass sich das Element wiederholen kann.
Weiterführende Überlegung
Siehe hierzu auch
XmlBuilder, XmlDocument
Siehe hierzu auch
JdomUtil
Achtung: Erweiterungen und Fixes stelle ich ohne Historie
und ohne Ankündigung hier bereit. Lizenzbedingungen:
Die Programme, Quelltexte und Dokumentationen können ohne
irgendwelche Bedingungen kostenlos verwendet werden. |