Heiner KückerXML Really Pull Parser |
|
|
Home Java-Seite . Weiterentwicklung_Java . WebCam_Demo . JSP WorkFlow . PageFlow FlowControl . Page Flow Engine . Web Flow Engine . Control_and_Command . JSP_Spreadsheet . 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 . Constraint Class . Code Generator 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. |