Probleme beim SAX parsing

Status
Nicht offen für weitere Antworten.
D

DerUnwissende

Gast
Hallo zusammen, ich habe folgendes Problem:

Ich entwickle gerade zum ersten mal eine Client-Server Anwendung und möchte für die Kommunikation XML verwenden. Beim Parsing des InputStreams des Sockets mit SAXParser und einer von DefaultHandler abgeleiteten Klasse wird nun jedoch nicht die endDocument Methode aufgerufen, der Parser scheint einfach weiterhin zu glauben, dass das Dokument noch nicht zu Ende ist. Deshalb kann ich natürlich keine weiteren Dokumente schicken, ohne eine SAXException zu bekommen.
Woran liegt das? Wie kann ich das umgehen, ohne auf SAX zu verzichten, oder die Verbindung nach jeder Datei neu aufbauen zu müssen?

Hier erstmal der der das Dokument sendet:
Code:
TransformerFactory tFactory= TransformerFactory.newInstance();
Transformer t= tFactory.newTransformer();
DOMSource source = new DOMSource(doc);

synchronized(s){      //s ist ein Socket
	StreamResult result = new StreamResult(s.getOutputStream());
	t.transform(source, result);
}

Hier ein Teil des empfangenden Threads der den Parser in einer Schleife aufruft:
Code:
		while(!close){
		     try{
				Debug.out("start of parsing loop");
				DefaultHandler handler=new ServerHandler(this, connection);
				SAXParserFactory factory = SAXParserFactory.newInstance();
			        SAXParser saxParser = factory.newSAXParser();
		    	        saxParser.parse( connSocket.getInputStream(), handler ); 
//der Thread blockiert hier und wartet auf Anfragen vom Client.

		    }catch(ParserConfigurationException pce){
		    	Debug.out(pce.getMessage());
		    	pce.printStackTrace();
		    }catch(IOException ioe){
		    	Debug.out("IOException while parsing (maybe interrupted): "+ioe.getMessage());
		    	
		    }catch(SAXException saxe){
		    	Debug.out("SAXExceptin while parsing (maybe interrupted): "+saxe.getMessage());
		    }finally{
		    	if (connSocket.isClosed()){
		    		//TODO wrong!!!
		    		if(close)
		    			Debug.out("Connection closed Client Sided!");
		    		else{
		    			close=true;
		    			Debug.out("Connection closed Server Sided!");
		    		}
		    	}
		    }
		}
Beispiel XML Datei die ich getestet habe
Code:
<?xml version="1.0" encoding="UTF-8"?><TEST_1><TEST_2><TEST_3/></TEST_2><TEST_4/></TEST_1>
Ich möchte den ersten Thread jetzt mal nicht weiter mit evt. unnötigem Quelltext überladen, wenn ihr mehr infos braucht einfach schreiben

Vielen Dank schonmal im Voraus
 
K

kleiner_held

Top Contributor
Ah ja, ich entsinne mich dunkel dieses Problem auch mal gehabt zu haben.
Die Ursache ist, dass der Parser (getestet mit Xerces) kein endDocument aufruft bis der InputStream ein -1 beim read zurueckgibt. Unangenehm ist ausserdem, dass der Parser, wenn er fertig ist, ein close() am InputStream aufruft und dir damit die Verbindung zumacht.

Das stand auch irgendwo versteckt in der Java API zu org.xml.sax.InputSource
Java API hat gesagt.:
An InputSource object belongs to the application: the SAX parser shall never modify it in any way (it may modify a copy if necessary). However, standard processing of both byte and character streams is to close them on as part of end-of-parse cleanup, so applications should not attempt to re-use such streams after they have been handed to a parser.

Die saubere Lösung wäre, alle zu sendenen Dokumente in einem neuen XML Dokoment zusammenzufassen, also
mehrere Anfragen in einem neuen Root-Tag zu kapseln.
Statt
Code:
<root>Inhalt .. </root>  <root>Inhalt 2 .. </root>
die XML Struktur erweitern zu:
Code:
<neuerRoot><root>Inhalt .. </root>  <root>Inhalt 2 .. </root></neuerRoot>
Man arbeitet dann die ganze Verbindungszeit mit einem Parser und der verwendete Handler muss durch endElement das Ende der jeweiligen Abschnitte erkennen.

Wenn man eine vorgegebene XSD oder DTD hat und nebenbei eventuell validieren will oder bei bidirektionaler Kommunikation ist das manchmal ein wenig blöd.

Ich hatte mir damals auch einen "Hack" einfallen lassen und dem Sax-Parser quasi ein Ende des Inputs "untergeschoben". Der Client hat nach jedem vollstaendigen Senden eines XML Dokuments ein ASCII Steuerzeichen (SUB 0x1A) in den Ausgabestrom eingefuegt.
Auf serverseite wird der Eingabestrom mit einem speziellen FilterInputStream gekapselt, der beim Erhalt des Steuerzeichens ein StreamEnde signalisiert (return -1) bis er mit setInterrupted(false) wieder freigeschaltet wird. Ausserdem verschluckt er alle close() Aufrufe. Ist aber wie gesagt ein ziemlich haesslicher Hack, aber eine bessere loesung ist mir damals net eingefallen.

Bei dir waere der Aufruf dann so:
Code:
      InterruptableInputStream interruptableInputStream = new InterruptableInputStream(connSocket.getInputStream());
      while(!close){
         try{
            Debug.out("start of parsing loop");
            DefaultHandler handler=new ServerHandler(this, connection);
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();
                  saxParser.parse(interruptableInputStream, handler ); 
            // nach dem Lesen wieder freischalten
            interruptableInputStream.setInterrrupted(false);
	...

Code:
    public class InterruptableInputStream extends PushbackInputStream
    {
        private boolean interrrupted = false;
        private byte stopChar = 0x1A;
        
        public InterruptableInputStream(InputStream in)
        {
            super(in, 2048);
        }
        
        public int read() throws IOException
        {
            if (interrrupted)
            {
                return -1;
            }
            int read = super.read();
            if (read == stopChar)
            {
            	setInterrrupted(true);
            	return -1;
            }
            return read;
        }

        public int read(byte[] b, int off, int len) throws IOException
        {
            if (interrrupted)
            {
                return -1;
            }
            // if there are unread bytes in the buffer, we do first empty the buffer
            // otherwise we have to ensure to read max one more byte as buffer space is available
            // (one more byte is possible, because we do only push back if there is a stopChar 
            // found and we never push back the stopChar)
            int read = super.read(b, off, Math.min(len, // never more than the caller allows
            		super.pos == super.buf.length ?     // buffer empty ?  
            		super.pos + 1 :                     // yes -> one byte more than buffer spaces is available
            		super.buf.length - super.pos));     // no  -> the buffer content
            
            // check the read bytes for the stopChar, if it was found then push back all bytes behind the
            // stopChar and return only the bytes until there
            if (read > 0)
            {
            	for (int i = 0; i < read; i++)
            	{
            		if (b[i+off] == stopChar)
            		{
            			unread(b, off+i+1, read-i-1);
            			setInterrrupted(true);
                		return i;
            		}
            	}
            }
            return read;
        }

        public boolean isInterrrupted()
        {
            return interrrupted;
        }

        public void setInterrrupted(boolean interrrupted)
        {
            this.interrrupted = interrrupted;
        }
        
        public void close() throws IOException
        {
        	// ignore the close
        }
    }
 
D

DerUnwissende

Gast
OK, der Hinweis hilft mir auf jeden Fall schonmal weiter. Ich denke ich werde es nun so handhaben, alles in ein File zu schreiben, bis das Steuersignal kommt, und dann das File zu parsen. Mal schauen.

Vielen Dank auf jeden Fall für die Hilfe
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Probleme bei der Formatierung beim Einfügen und löschen über DOM XML & JSON 7
L Jackson JSON: Probleme beim einlesen XML & JSON 1
hdi Probleme beim Erstellen einer XML XML & JSON 7
F Probleme beim html parsen mit tagsoup XML & JSON 4
M Probleme beim Parsen eines gefilterten XML-Dokuments XML & JSON 6
H JAXB Probleme beim Unmarshalling XML & JSON 3
S Probleme beim erstellen einer Jar XML & JSON 12
C SAX Probleme beim lesen XML & JSON 4
byte Probleme beim Parsen von XHTML-Datei XML & JSON 4
R JAVA und DOM, probleme beim einfügen von elementen ?????? XML & JSON 6
Kirby.exe Probleme mit XML XPATH Select XML & JSON 3
G Probleme mit Jsoup in .jar File XML & JSON 11
K JAX-WS Bindin-Probleme XML & JSON 1
B Probleme mit RelativeLayout XML & JSON 1
K XOM Builder Probleme XML & JSON 3
N Jsoup: PHP-Tags bereiten Probleme? XML & JSON 2
M SAX-Parsing Probleme XML & JSON 23
M Probleme mit XPath bei Java XML & JSON 5
G Probleme mit XML und JTree XML & JSON 9
klattiator Probleme mit Codierung XML & JSON 3
T XML und Sonderzeichen, Probleme mit ASP.NET Server XML & JSON 2
G Probleme mit Namespaces XML & JSON 5
D Probleme mit Eclipse Modeling Framework (EMF) XML & JSON 2
S PDF Erzeugung - Probleme mit der XML Datei bei Schema-Infos XML & JSON 2
F JAXB - Nachträglich hinzugefügter Code macht Probleme XML & JSON 2
P Probleme mit JDom . addContent(int index,Collection c) XML & JSON 2
F Unmarshall Probleme XML & JSON 5
R Probleme mit Transformer und StreamResult XML & JSON 4
C Probleme mit Include XML & JSON 10
C POI + jXLS Probleme XML & JSON 3
B DOM DTD laden abschalten, Probleme mit Doctypes und PIs XML & JSON 2
S Probleme mit Jdom XML & JSON 3
G probleme mit package XML & JSON 12
M Probleme mit String XML & JSON 3
H Probleme mit xmlrpc und php XML & JSON 13
B Probleme mit Zugriff auf eXist-Datenbank XML & JSON 9
H Neu bei JAVA- Probleme mit der Integration von Xerces XML & JSON 3
P Probleme mit jdom XML & JSON 5
S Hilfe beim RDF-Graphen XML & JSON 0
R Beim Serialisieren fehlt die letzte Zeile XML & JSON 5
A Leeres Array beim Auslesen von XML-Datei XML & JSON 4
A XML-Fehler beim Prefix von xmlns XML & JSON 2
K Beim Parsen einer XML-Datei Connection timed out XML & JSON 4
G Langsam beim SAX-Parsen - woran liegts? XML & JSON 2
A Fehler beim Erzeugen eines XML-Schema XML & JSON 4
B Validierung nur beim einlesen oder auch beim schreiben? XML & JSON 4
D JAXBException beim Marshaller XML & JSON 4
M Read / write Problem beim ByteStrom XML & JSON 2
whitenexx Problem beim parsen von Facebook XML XML & JSON 3
J Dateinamen beim Start auslesen XML & JSON 8
F Hilfe beim bearbeiten von XML elemente XML & JSON 3
N XStream ConversionException beim Deserialisieren in (Hibernate)Objekt XML & JSON 6
G Problem beim schreiben von XML in eine File XML & JSON 2
L Reihenfolge beim xml Datei parsen einhalten? XML & JSON 8
sylo Beim Erzeugen einer XML Datei auch die XML Struktur erzeugen? XML & JSON 11
B Problem beim löschen von ChildNodes aus einem XML-DOM XML & JSON 3
E JDOM - Problem beim Zusammenfügen zweier Dateien XML & JSON 2
N Hilfe beim Einstieg in EMF XML & JSON 6
D Das Programm hängt etwa 5 Sekunden beim Aufruf der parse-Methode XML & JSON 6
D Tabs/Einrückungen der XML-Elemente gehen beim Schreiben verloren XML & JSON 5
T Problem beim Parsen von Attribut xmlns="urn:com:test&qu XML & JSON 6
G XML Tag beim Einlesen manipulieren XML & JSON 2
J Problem beim XML-Lesen XML & JSON 2
N jdom problem beim lesen von child elementen XML & JSON 5
P NullPointerException beim Auslesen XML & JSON 8
M Performance beim Binding XML & JSON 2
E XOM setzen von XML-Schema declaration beim erzeugen XML-File XML & JSON 2
J Fehler beim laden einer .xml XML & JSON 3
G DOCTYPE Problem beim Transformer/TransformerFactory etc. XML & JSON 13
P OutOfMemoryError beim Einlesen einer XML-Datei XML & JSON 7
P Problem beim erstellen eines neuen Elements (JDOM) XML & JSON 5
S JDOM-Kein indent beim XMLOutputter XML & JSON 4
C Zeile herausfinden in der ein Fehler beim Einlesen entsteht XML & JSON 3
V Datenverlust nach sortieren (nur beim serialisieren) XML & JSON 4
S Problem beim Erstellen eines pdfs XML & JSON 3
R Problem beim Auslesen von Attributen XML & JSON 4
M Gson Enum parsing XML & JSON 0
M XML Parsing von Paketen XML & JSON 12
T XML-Parsing: Whitespace zw. Elementen wird nicht ignoriert XML & JSON 4
O Parsing bricht ab XML & JSON 11

Ähnliche Java Themen


Oben