# SAX Probleme beim lesen



## (c)hris (12. Jul 2007)

Hallo zusammen,

ich habe folgendes Problem:

Ich parse eine XML-Datei mit SAX, habe also meinen eigenen "DefaultHandler" geschrieben.
Soweit so gut. Mit kleinen Testdateien funktioniert die Sache ganz gut.

In der XML-Datei gibt es ein Datumsfeld welches ich auslese und mittels DateFormat in ein Date wandle.
Hierbei stelle ich fest, daß ich recht häfig folgendes bekomme

java.text.ParseException: Unparseable date: ":47:37+02:00"

Der Tag in der Datei ist dieser "2006-05-03T12:47:37+02:00"

Es sieht für mich aus, als würde der Parser bis zu einem bestimmten Puffer lesen und dann verarbeiten, nur das der Date-Tag hier nicht komplett ist.

Hat jemand eine Idee wie ich das vermeiden kann.

hier noch mein Sourcecode:


```
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

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


public class Test extends DefaultHandler
{
	private String CurrentNodeValue;
	private Changeprocess cp;
	private ChangeSignature cs;
	private List<Changeprocess> list = new ArrayList<Changeprocess>();
	private ChangeObject co;
	private ChangeId id;
	
	public static void main(String[] args) throws ParserConfigurationException,IOException
	{
		Test test = new Test();
		SAXParserFactory factory = SAXParserFactory.newInstance();
		//factory.setValidating(false);
		SAXParser saxParser;
		try
		{
			saxParser = factory.newSAXParser();
			saxParser.parse(new File("F:\\Daten\\test.xml"), test);
			for(Changeprocess c: test.list)
			{
				System.out.println(c);
				System.out.println("-----------------------------------------------------------");
			}
		} catch (SAXParseException err) 
		{
			err.printStackTrace();
		} catch (SAXException e)
		{
			e.printStackTrace();
		}
		

	}


	public static Date translateDate(String str)
	{
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'H:mm:ss");
		Date date=null;
		try
		{
			date = df.parse(str);
		} catch (ParseException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return date;
	}
	public void endElement(String uri, String localName, String qName) throws SAXException
	{
		if(qName.equals("operator"))
		{
			cp.setOperator(CurrentNodeValue);
		}
		else if(qName.equals("begin_date"))
		{
			cp.setBegin_date(translateDate(CurrentNodeValue));
		}
		else if(qName.equals("change_type"))
		{
			cp.setChange_type(CurrentNodeValue);
		}
		else if(qName.equals("change_status"))
		{
			cp.setChange_status(CurrentNodeValue);
		}
		else if(qName.equals("ds_count_required"))
		{
			cp.setDs_count_required(Integer.parseInt(CurrentNodeValue));
		}
		else if(qName.equals("ticket"))
		{
			cp.setTicket(CurrentNodeValue);
		}
		else if(qName.equals("ticket"))
		{
			cp.setTicket(CurrentNodeValue);
		}
		else if(qName.equals("signature_date"))
		{
			cs.setSignature_date(translateDate(CurrentNodeValue));
		}
		else if(qName.equals("signature"))
		{
			cs.setSignature(CurrentNodeValue);
		}
		else if(qName.equals("serial_key_number"))
		{
			cs.setSerial_key_number(Integer.parseInt(CurrentNodeValue));
		}
		else if(qName.equals("id"))
		{
			id.setValue(CurrentNodeValue);
		}
	}

	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
	{
		if(qName.equals("changeprocess"))
		{
			cp = new Changeprocess();
			list.add(cp);
			
			int length = attributes.getLength(); 
	        for(int a = 0; a<length; ++a ) 
	        {
	        	String attribqName = attributes.getQName(a);
	        	if(attribqName.equals("client_id"))
	        	{
	        		cp.setClient_id(Integer.parseInt(attributes.getValue(a)));
	        	}
	        	else if(attribqName.equals("chg_process_id"))
	        	{
	        		cp.setChg_process_id(Long.parseLong(attributes.getValue(a)));
	        	}
	        }
		}
		else if(qName.equals("changesignature"))
		{
			cs = new ChangeSignature();
			cp.addSignature(cs);
			
			int length = attributes.getLength(); 
	        for(int a = 0; a<length; ++a ) 
	        {
	        	String attribqName = attributes.getQName(a);
	        	if(attribqName.equals("operator"))
	        	{
	        		cs.setOperator(attributes.getValue(a));
	        	}
	        }
		}
		else if(qName.equals("object"))
		{
			co = new ChangeObject();
			cp.addChangeobject(co);
			
			int length = attributes.getLength(); 
	        for(int a = 0; a<length; ++a ) 
	        {
	        	String attribqName = attributes.getQName(a);
	        	if(attribqName.equals("type"))
	        	{
	        		co.setType(attributes.getValue(a));
	        	}
	        	else if(attribqName.equals("change_valid_state"))
	        	{
	        		co.setChange_valid_state(attributes.getValue(a));
	        	}
	        	else if(attribqName.equals("pk_fields"))
	        	{
	        		co.setPk_fields(attributes.getValue(a));
	        	}
	        }
		}
		else if(qName.equals("id"))
		{
			id = new ChangeId();
			int length = attributes.getLength(); 
	        for(int a = 0; a<length; ++a ) 
	        {
	        	String attribqName = attributes.getQName(a);
	        	if(attribqName.equals("type"))
	        	{
	        		id.setType(attributes.getValue(a));
	        	}
	        }
	        co.addChangeId(id);
		}
	}

	public void characters(char[] buf, int offset, int len)
	{
		String s = new String(buf,offset,len);
		if(s.indexOf ( "\n" )   <  0 && s.length() > 0)
		{
			this.CurrentNodeValue = s;
		}
	}
}
```


----------



## Zed (12. Jul 2007)

Hm ganz ehrlich gesagt kein Plan warum das passiert.

Vielleicht interpretiert der den : als Trennzeichen.

Ich würde es vielleicht gleich mit einem Timetamp probieren. 

Auf den zweiten Blick
SimpleDateFormat("yyyy-MM-dd'T'H:mm:ss") passt das irgendwie nicht zu 2006-05-03T12:47:37+02:00

SimpleDateFormat("yyyy-MM-dd'T'H:mm:ssZ") dann sollte das Datum ungefähr so aussehen 2006-05-03T12:47:37+0200


----------



## (c)hris (12. Jul 2007)

Erstmal Danke.

Das Scheitern der Datekonvertierung ist aber nur das Endergebnis.

Wenn ich das Datum nur als String verarbeite wird es abgeschnitten:

Ich packe die Daten alle in eine Bean jedoch wird diese nicht komplett gefüllt.

z.B.

Wert in der XML-Datei           -> Wert in der Bean
2006-05-03T12:47:37+02:00 -> :47:37+02:00 
2006-05-03T12:47:37+02:00 -> 2006-05- 
2006-05-03T12:47:37+02:00 -> 05-03T12:47:37+02:00 
2006-05-03T12:47:37+02:00 -> +02:00 
2006-05-03T12:47:37+02:00 -> 3T12:47:37+02:00 
usw.^

ps. Das Problem ist leider auch, daß ich auf die XML-Datei keinen Einfluß habe. Die bekomme ich aus einem anderen System.


----------



## Guest (20. Jul 2007)

hallo,
ich vermute das die content methode 2mal hintereinander aufgerufen wird. 
versuch es mal mit      
	
	
	
	





```
this.CurrentNodeValue = this.CurrentNodeValue + s;
```
anstatt        
	
	
	
	





```
this.CurrentNodeValue = s;
```


----------



## kleiner_held (20. Jul 2007)

Ja, die characters(...) Methode kann mehrmals für die gleiche Node aufgerufen werden.
Ich würde aus Performancegründen einen StringBuilder als Puffer verwenden.
In der endElement Methode musst du auf alle Fälle nach dem auswerten des Contents den Puffer wieder leeren.


----------

