Handler-Wechsel, SAX Parser bricht nach 8192 Byte ab

R

Rusti

Gast
Hallo Gemeinde,

ich habe ein Problem beim Parsen von XML Dokumenten mittels des SAXParsers. Ich nutze den Parser zunächst mit einem allgemeinen Handler, welcher anhand des ersten erkannten Objektes einen speziellen Handler aufruft:

Methode zum Parsen:
Java:
	public static Object parseXML(byte[] b) {
		ByteArrayInputStream bs = new ByteArrayInputStream(b);
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			SAXParser parser = factory.newSAXParser();
			XML_Handler handler = new XML_Handler(parser, bs);
			parser.parse(bs, handler);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			System.out.println("Fehler beim Parsen des Dokuments!");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return parsing_result;
	}

Der allgemeine Handler:
Java:
public class XML_Handler extends DefaultHandler{
	
	public SAXParser parser;
	public ByteArrayInputStream bais;

	
	public XML_Handler(SAXParser psr, ByteArrayInputStream bs) {
		this.parser = psr;
		this.bais = bs;
	}

	@Override
	public void startDocument() throws SAXException {
		System.out.println("New Document started...");
	}
	/**
	 * Bei Erkennung eines Dokuments wird ein spezialisierter Handler an den Parser übergeben.
	 */
	@Override
	public void startElement(String uri, String localName,
			String qName, Attributes atts) throws SAXException {
		System.out.format("%s found!\n",qName);
		try {
			if ( qName.equals("Resolution_Data") ) {
                           this.parser.getXMLReader().setContentHandler(new ResData_Handler());
			}
			else if ( qName.equals("Scheduling_Data") ) {
                           this.parser.getXMLReader().setContentHandler(new                   
                           SchedData_Handler());
			}

                 ...............

			else {
				System.out.format("Kein Parser für den Dokumenttyp %s gefunden!",qName);
				this.parser.getXMLReader().setContentHandler(null);
			}
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

Die speziellen Handler machen nicht aufregendes, sie sortieren die Gefundenen Elemente bzw. deren Inhalt mittels startElement() und characters() in die entsprechenden Datenstrukturen. Alles funktioniert wunderbar mit kleinen Dateien (<8kb).

Bei Dateien, welche die Kapazität des char[]-Arrays allerdings überschreiten wird es problematisch.
Wenn ich während des Parse-Vorgangs den Content Handler wechsle, wird nach Beendigung des aktuellen "char[]" Arrays kein neues mehr angefangen und der Vorgang bricht mit "XML document structures must start and end within the same entity." ab... Habe die Sache inzwischen soweit eingegrenzt, dass die Datei nach 8192Byte schlicht nicht weiter eingelesen wird.
Wenn ich diesen Hanlderwechsel nicht durchführe läuft der Parser ohne murren durch und beginnt ohne Weiteres die nächsten 8192 Byte.

Ich finde zu der Thematik leider nicht einmal Anhaltspunkte im Netz.
Kennt sich hier evtl. jemand mit der Geschichte aus und hat ein paar Hinzweise für mich? :)

Beste Grüße

Rusti
 
Zuletzt bearbeitet von einem Moderator:

musiKk

Top Contributor
Kannst Du die Handler vielleicht noch zeigen?

Weiß aber noch nicht, ob das hilft. Ideal wäre natürlich ein möglichst kurzes Beispiel, welches den Fehler demonstriert (bei der XML-Datei sollte eine Strukturbeschreibung reichen; 8kb sind für einen Post vielleicht etwas viel).
 
Zuletzt bearbeitet:
R

Rusti

Gast
Die Handler haben alle eine identische Form, der der zum Absturz führt ist der folgende:

Java:
package handlers;

import java.util.ArrayList;
import java.util.List;

import model.XML_Parser;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import sections.DBTSection;
import structures.Descriptor;
import structures.Scheduling_Information;
import structures.Table;
import structures.Descriptor.Descriptor_Content;
import structures.Scheduling_Information.Content_Provider;
import structures.Scheduling_Information.Programme;

public class Scheduling_Information_Handler extends DefaultHandler {
	
	public Scheduling_Information schi;
	public int cumlength;
	public int num_sections; 
	public int listlength; 
	public int bitcounter; 
	public int dsc_length; 
	public Table dbt;
	/**
	 * Eine Liste, welchen den Pfad des aktuellen Objektes enthält, z.B.
	 * { program_map_table, pmt_section, elementary_stream, es_descriptor, descriptor_tag }
	 */
	public List<String> current_object;

	public Scheduling_Information_Handler () {
		this.schi = new Scheduling_Information();
		this.dbt = new Table("DBT",68,1);
		this.current_object = new ArrayList<String>();
		current_object.add("scheduling_information");
	}
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		current_object.add(qName);

		if ( qName.equals("content_provider") ) {
			schi.content_providers.add(schi.new Content_Provider());
		}
		else if ( qName.equals("programme") ) {
			Content_Provider actprv = schi.content_providers.get(schi.content_providers.size()-1);
			actprv.programmes.add(schi.new Programme());
		}

               ............................. Hier kommen noch einige, die immer tiefer verschachtelte Strukturen aufbauen.....................................

	}
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		current_object.remove(current_object.size()-1);

	}
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if ( ch[start] == '\n' ) return;
		String curobj = current_object.get(current_object.size()-1);
		String prvobj = current_object.get(current_object.size()-2);
		StringBuilder result = new StringBuilder();
		for (int i=start; i < (start + length); i++) result.append(ch[i]);
		Content_Provider actprv = schi.content_providers.get(schi.content_providers.size()-1);
		
		if ( curobj.equals("event_component_id") ) {
			Programme actpro = actprv.programmes.get(actprv.programmes.size()-1);
			Scheduling_Information.Event actevt = actpro.events.get(actpro.events.size()-1);
			Scheduling_Information.Event_Component actcmp = actevt.event_components.get(actevt.event_components.size()-1);
			actcmp.event_component_id = Integer.parseInt(result.toString());
		}
		else if ( curobj.equals("dbt_id") ) {
			actprv.dbt_id = Integer.parseInt(result.toString());
		}

.................................. hier werden dann die Inhalte der Elemente in die oben erzeugte Datenstruktur eingelesen.................................................


@Override
	public void endDocument() throws SAXException {

.............. Hier erfolgt das setzen von Werten in der aufgebauten Datenstruktur, z.b. Bestimmung der Länge der erzeugten Substrukturen.............................
}

Die endDocument() habe ich mal rausgeschnitten, da kommt der Parser aber auch definitiv nicht mehr an. Ich habe mich soweit rangetastet, dass der Abbruch beim Erreichen des Endes des char[] Arrays auftritt. Normalerweise liest des Parser ja zum Ende hin einfach den nächsten Teil der Quelldatei ein. Nach einem Wechsel des Handlers ist aber wie gesagt Schluss wenn er das Ende erreicht. Schonmal vielen Dank fürs angucken!

Rusti
 
S

SlaterB

Gast
meiner Philosphie nach sollte man so eine Blackbox wie den Parser so wenig wie nötig belasten,
warum musst du den Handler wechseln, was macht ein Handler schon mehr als auf die paar Tag-Ereignisse zu reagieren?

du köntest doch einen Handler X setzen, der alle Events an einen intern aktuell gesetzten zweiten Handler weiterleitet,
anfangs an den XML_Handler, später dann evtl. ResData_Handler oder was anderes,

offensichtlich kann es dann an sich nicht zu einem derartigen Fehler kommen, X bleibt gleich,
was innerhalb von X passiert ist vollständig unter deiner Kontrolle, dem Parser dürfte das allen Naturgesetzen nach ganz egal sein,
 
R

Rusti

Gast
@SlaterB:

Das ist schonmal eine gute Idee, sollte wie Du sagst nach allen gängigen Gesetzen funktionieren.
Ich werde die Problematik erstmal auf diese Weise umschiffen, auch wenn das ganze natürlich einen deutlichen Verlust an "Eleganz" mit sich zieht...

In der JavaDoc zum Parser steht ausdrücklich "Applications may register a new or different handler in the middle of a parse, and the SAX parser must begin using the new handler immediately."

Also müsste da doch was zu machen sein #]

Auf jeden Fall vielen Dank!

Rusti
 
R

Rusti

Gast
.....steinigt mich, bewerft mich mit Mist!
Stelle gerade fest, dass die Problematik dadurch entsteht, dass ich das Dokument anderer Stelle noch auf falsche und kaputte Weise validiere... wenn ich die Geschichte raus nehme flutscht auch der Handlerwechsel!

Also nochmals vielen Dank und Entschuldigung ;)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
pkm Gibt es XML-Parser-Bibliotheken XML & JSON 3
B XML-Daten mit SAX Parser verarbeiten in Java XML & JSON 4
MiMa SAX-Parser beenden? XML & JSON 5
K GSON-Parser XML & JSON 6
K XML-Parser vs. XLST XML & JSON 4
L DOM Parser Implementieren XML & JSON 9
M SAX Parser implementieren XML & JSON 2
E Gibt es denn einen XML-Parser für JUnit-Tests? XML & JSON 6
D XSD Parser XML & JSON 1
T Neuer XML Parser!!! XML & JSON 33
J XML Parser anhand xsd erzeugen XML & JSON 2
H SAX Parser optimieren XML & JSON 5
H Sax Parser verschluckt teile XML & JSON 11
C XML SAX Parser XML & JSON 10
B SAX-Parser - Dokumente einlesen und in einer Map ablegen XML & JSON 2
S Sax Parser Performance XML & JSON 2
M Eigener XML-Parser XML & JSON 1
S Typsicherer HTML-Parser XML & JSON 5
S HTML Parser XML & JSON 2
B Parser und Fabrik XML & JSON 6
F SAX Parser siehe nichts auf dem Konsole weder eine Fehlermeldung noch eine Ergebnis XML & JSON 6
enne87 SAX-Parser XML & JSON 5
C Mit SAX Parser XML Attribute auswerten XML & JSON 3
H XML-Parser: geparste Strings in Konstruktor? XML & JSON 9
S DOM Parser XML & JSON 12
S Sax Parser XML & JSON 3
D Speicherüberlauf bei character-Methode mit SAX-Parser XML & JSON 3
Y Welchen XML Parser / Klassen aus XSD generieren lassen XML & JSON 4
H Brauche ich einen speziellen XML-Parser? XML & JSON 2
M Unhierarchisches XML-File mit DOM-Parser auswerten XML & JSON 5
G XML Parser Fehler, zwei gleiche kind-Elemente XML & JSON 7
S Welcher XML-Parser am besten? XML & JSON 4
S Parser XML & JSON 2
S JAVA XML Parser der einen String parst XML & JSON 3
Noar XML-Parser mit GUI? XML & JSON 2
R Problem mit SAX-Parser characters() XML & JSON 7
K SAX Parser Character Puffer zu klein XML & JSON 2
B Mit Sax-Parser validieren XML & JSON 7
Wildcard xpath Parser XML & JSON 8

Ähnliche Java Themen

Neue Themen


Oben