Parsing bricht ab

Status
Nicht offen für weitere Antworten.

oschli

Mitglied
Hi,

nachdem ich in einem anderen Thread nach einer Konkatenation von XML Files gefragt habe(Siehe Link). Wurde mir gerate die XML-Files mit SAX zu parsen.

www.java-forum.org/de/viewtopic.php?t=28730

Dies habe ich durch den unten stehenden Code realisiert. Allerdings bricht das Parsen bei einer bestimmten Größe der XML Files ab. Und zwar an der Stelle wo ich das Datum einlesen will.

Es wird dann an stelle von 02-01-2006 nur noch 02-01-20 ausgegeben. Da die Funktion public void characters(char ch[], int start, int length) nur noch mit den Parametern start=2040 length=8 aufgeufen wird. Bei den läufen davor jedoch mit length gleich=10.

Woran könnte das liegen?

Code:
package monitoringclient.logic;

import java.util.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

import monitoringclient.model.MyDisk;
import monitoringclient.model.MyInstance;
import monitoringclient.model.MyPing;




public class MyEventHandler extends DefaultHandler {
	
	

	public MyEventHandler (){

		myInstanceList_=new LinkedList();
	 
	}
	
	public void startElement(String uri, String qname, String name, Attributes atts){
		
		if(name.equalsIgnoreCase("Instance")){
			aMyInstance_= new MyInstance();
		}
		else if(name.equalsIgnoreCase("Hostname")){
			currentElement="Hostname";
		}
		else if(name.equalsIgnoreCase("Port")){
			currentElement="Port";
		}
		else if(name.equalsIgnoreCase("Date")){
			currentElement="Date";
		}
		else if(name.equalsIgnoreCase("Time")){
			currentElement="Time";
		}
		else if(name.equalsIgnoreCase("SMTP")){
			 aPing_ = new MyPing();
		}
                .... noch weitere zuweisungen
		else{
			currentElement="nothing";
		}
	}
	
	public void endElement(String uri, String name, String qname){
		if(qname.equalsIgnoreCase("Instance")){
			//myInstanceList_.add(aMyInstance_);
			//startParsing
			System.out.println("Eventueller start von Parsing");
			this.aMyInstance_=null;
		}
		else if(qname.equalsIgnoreCase("SMTP")){
			aMyInstance_.setSMTP(aPing_);
			aPing_=null;
		}
		else if(qname.equalsIgnoreCase("DB")){
			aMyInstance_.setDB(aPing_);
			aPing_=null;
		}
		else if(qname.equalsIgnoreCase("Disk")){
			aMyInstance_.addDisk(aDisk_);
			aDisk_=null;
			
		}
		
	}
	
	
	
	public void characters(char ch[], int start, int length){
		String value = new String (ch, start, length);
		if(!value.trim().equals("")){
			
			if(currentElement.equalsIgnoreCase("Hostname")){
				aMyInstance_.setHostname(value);
			}
			else if(currentElement.equalsIgnoreCase("Port")){
				aMyInstance_.setPort(value);
			}
			else if(currentElement.equalsIgnoreCase("Date")){
				System.out.println(value);
				aMyInstance_.setDate(value);
			}
			else if(currentElement.equalsIgnoreCase("Time")){
				System.out.println(value);
				aMyInstance_.setTime(value);
			}
			...
			noch adds			
		}
	}

	
	public LinkedList getInstance(){
		return this.myInstanceList_;
	}
	
	
	private LinkedList myInstanceList_;
	private String currentElement;
	private MyInstance aMyInstance_;
	private MyPing aPing_;
	private MyDisk aDisk_;

}
 
R

Roar

Gast
es ist nicht garantiert, dass characters() für jeden Text abschnitt genau einmal aufgerufen wird. du musst damit rechnen, dass characters() mehrmals hintereinander aufgerufen wird und den string teilweise liefert. mach mal ein println() an den anfang der characters() methode und die gelieferten zeichen aus.
 

oschli

Mitglied
Das gibt er beim Fehler aus.


Code:
<Instance ID="1"><Hostname>liyy001</Hostname><Port>7001</Port><Date>02-01-2006</Date><Time>09:00:01</Time>
<Instance ID="1"><Hostname>liyy001</Hostname><Port>7001</Port><Date>02-01-20
monitoringclient.date.MyDate$WrongDate
	at monitoringclient.date.MyDate.<init>(MyDate.java:61)
	at monitoringclient.model.MyInstance.setDate(MyInstance.java:31)
	at monitoringclient.logic.MyEventHandler.characters(MyEventHandler.java:127)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.characters(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanContent(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
	at javax.xml.parsers.SAXParser.parse(Unknown Source)
	at javax.xml.parsers.SAXParser.parse(Unknown Source)
	at monitoringclient.TestApplication.main(TestApplication.java:95)
06</Date><Time>09:30:01</Time>

Warum funktioniert es dann bis dahin? Reines Glück ?
 
R

Roar

Gast
"06</Date><Time>09:30:01</Time> "
:autsch:
wie geht das denn, is dein xml kaputt? zeig mal die entsprechenden tags (oder is das in einer cdata section?)

> Warum funktioniert es dann bis dahin? Reines Glück ?
ja, anscheinend :)
du musst halt das, was characters() übergibt zwischenspeichern und deine nstring daraus zzusammensetzen.

edit: ich frag mich noch immer, warum da die tags übergeben werden? :?
 

oschli

Mitglied
Genau nach 40 solcher Instanzen bricht er ab.
Code:
<Instance ID="1">
	<Hostname>liyy001</Hostname>
	<Port>7001</Port>
	<Date>01-01-2006</Date>
	<Time>07:00:02</Time>
	<SMTP>
		<Hostname>LIPC175</Hostname>
		<Reply>Failed</Reply>
		<Replytime>100</Replytime>
	</SMTP>
	<DB>
		<Hostname>LIPC175</Hostname>
		<Reply>Failed</Reply>
		<Replytime>100</Replytime>
	</DB>
	<OS>
		<CPULoad>0.67</CPULoad>
		<Filesystem>
			<Disk>
				<Name>/dev/hda2</Name>
				<UsedSpace>7</UsedSpace>
			</Disk>
		</Filesystem>
		<Swap>
			<SwapUsed>0</SwapUsed>
			<SwapTotal>1032152</SwapTotal>
		</Swap>
	</OS>
	<***>
		<Applikation>
			<State>UP</State>
		</Applikation>
		<License>
			<SI>
				<Floating>
					<Number>0</Number>
					<User/>
				</Floating>
			</SI>
			
		</License>
		<Trigger>
			<TriggerInformation>
				<Client>IM</Client>
				<Name>checkAccount</Name>
				<Success>0</Success>
				<Total>0</Total>
			</TriggerInformation>
			
		<***Cache>
			<Percent>0.25</Percent>
			<UsedBytes>1048576</UsedBytes>
		</***Cache>
	</***>
</Instance>
 
R

Roar

Gast
tjo, wie gesagt: speicher die werte die characters() kriegt zwischen, und bastel dir daraus wenn alles da ist nen string.
 
R

Roar

Gast
hm auf die schnelle fällt mir ein:
instanzvariable StringBuilder characterBuffer;
in der characters() methode steht *nur*: characterBuffer.append(new String(...));
das if(currentElement...) ... currentElement.setXXX(characterBuffer.toString()); steht dann in der methode endElement(). am ende der endElement() nicht vergessen den buffer zu löschen: characterBuffer.setLength(0);
 

oschli

Mitglied
Da bekomm ich immer ne NullPointerException bei append.
Code:
public void characters(char ch[], int start, int length){
		String value=new String(ch, start, length);
		if(!value.trim().equals("")){
			System.out.println(value);
			characterBuffer.append(value);
		}
	}
 

Bleiglanz

Gesperrter Benutzer
ich würde die abfrage auf "" weglassen

roar mein folgendes


character Event:
============

wenn vorheriger Event KEIN character event, dann neuen StringBuilder machen und char[]s ansammeln

wenn vorheriger Event ein character event war, dann weiter ansammeln in einem StringBuilder;

beliebiger Event:
============

wenn vorheriger Event ein character Event, dann diese char -Sammlung "abschliessen", d.h. den ganzen String aus dem StringBuilder holen und verarbeiten


is leider etwas kompliziert, geht aber nicht anders - weil du sonst nicht erkennen kannst, wann dein String fertiggebaut ist

liegt am Puffern des SAX-Parsers, soll ja effizient sein :)
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben