# Sax Parser verschluckt teile



## Holger (16. Jan 2012)

Hi Leute, 

ich verwende momentan den SaxParser um XML Dateien zu parsen. Funktioniert soweit auch sehr gut, das einzigste Problem ist, das der Parser Stellen wie "Das... blabliblu... blabla..." teilweise verschluckt. Er gibt quasi nur blabla... aus. Ich verstehe nur nicht warum habe keinerlei Einschränkung programmiert die dieses Verhalten erzeugen würde. 

Hoffe mir kann jemand Informationen zu diesem Problem geben. Hab auch gegooglet aber nicht entsprechendes gefunden.

Mit freundlichen Grüßen 
Holger


----------



## eRaaaa (16. Jan 2012)

Zeig uns doch mal ein Beispiel mit einer kleine Beispiel-XML-Datei und Beispielcode(Java-Code)


----------



## Noctarius (16. Jan 2012)

characters wird mehrere Male aufgerufen, du musst dich selber darum kümmern, die Strings per StringBuilder zusammen zubauen.


----------



## Holger (16. Jan 2012)

Danke erstmal für die schnelle Reaktion!

Also die XML-Datei würde beispielhaft so aussehen:

[XML]
<item>
<title>Converse The Great Escape Contest</title>
<link>
Unix/FreeBSD Web Hosting für Profis
</link>
<description>
Beschreibung... Beschreibung... Beschreibung...
</description>
<content:encoded>
<![CDATA[
<img src="IMG-URL" width="65" height="65" border="0" alt="" /> Content. Content. Content.
]]>
</content:encoded>
<category>Kategorie</category>
<pubDate>PubDate</pubDate>
[/XML]

Wobei es nicht sein muss das die Beschreibung die drei Punkte(...) enthalten muss. Hierbei tritt lediglich der Fehler auf.

SaxParser:

```
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

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

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import android.util.Log;


public class VideoNewsParser {
	
	private ArrayList<VideoNews> newslist;
	public boolean rdy  = false;
	private static final String TAG = "Class :VideoNewsParser";
	
	public VideoNewsParser(){
		try {
			
			URL url = new URL("URL der XML Datei");
			SAXParserFactory saxparserfactory = SAXParserFactory.newInstance();
			saxparserfactory.setNamespaceAware(true);
			SAXParser saxparser = saxparserfactory.newSAXParser();
			
			XMLReader xmlreader = saxparser.getXMLReader();
			
			VideoNewsHandler textnewshandler = new VideoNewsHandler();
			xmlreader.setContentHandler(textnewshandler);
			xmlreader.parse(new InputSource(url.openStream()));
			
			newslist = textnewshandler.getVideoNewsList();
			rdy = true;
			
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			Log.e(TAG, "MalformedURLException");
			rdy = false;
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			Log.e(TAG, "ParserConfigurationException");
			rdy = false;
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			Log.e(TAG, "SAXException");
			rdy = false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Log.e(TAG, "IOException");
			rdy = false;
		}
	}
	
	public ArrayList<VideoNews> getList(){
		return newslist;
	}
	
	
}
```

Der Handler:

```
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

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

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;


public class VideoNewsHandler extends DefaultHandler{
	private boolean in_item = false;
	private boolean in_title = false;
	private boolean in_link = false;
	private boolean in_description = false;
	private boolean in_content = false;
	private boolean in_category = false;
	private boolean in_date = false;
	
	private ArrayList<VideoNews> videoNewsList = new ArrayList<VideoNews>();
	private VideoNews vn;
	
	/**
	 * @return the videoNewsList
	 */
	public ArrayList<VideoNews> getVideoNewsList() {
		return videoNewsList;
	}
	
	public void startDocument() throws SAXException{
		
	}
	
	public void endDocument() throws SAXException{
		
	}
	
	public void startElement(String URI, String localName, String qName, Attributes attributes) throws SAXException {
		if(localName.equals("item")){
			vn = new VideoNews();
			in_item = true;
		}
		else if(localName.equals("title")){
			in_title = true;
		}
		else if(localName.equals("link")){
			in_link = true;
		}
		else if(localName.equals("description")){
			in_description = true;
		}
		else if(localName.equalsIgnoreCase("content:encoded") || qName.equals("content:encoded")){
			in_content = true;
		}
		
		
		else if(localName.equals("category")){
			in_category = true;
		}
		else if(localName.equals("pubDate")){
			in_date = true;
		}
	}
	
	public void endElement(String URI, String localName, String qName) throws SAXException {
		if(localName.equals("item")){
			in_item = false;
			videoNewsList.add(vn);
		}
		else if(localName.equals("title")){
			in_title = false;
		}
		else if(localName.equals("link")){
			in_link = false;
		}
		else if(localName.equals("description")){
			in_description = false;
		}
		else if(localName.equalsIgnoreCase("content:encoded") || qName.equals("content:encoded")){
			in_content = false;
		}
		else if(localName.equals("category")){
			in_category = false;
		}
		else if(localName.equals("pubDate")){
			in_date = false;
		}
	}
	
	public void characters(char[] charsequence, int start, int length){
		if(this.in_item && this.in_title){
			vn.setTitle(new String(charsequence, start, length));
		}
		if(this.in_item && this.in_link){
			vn.setLink(new String(charsequence, start, length));
		}
		if(this.in_item && this.in_description){
			vn.setDescription(new String(charsequence, start, length));
		}
		
		if(this.in_item && this.in_content){
			String content = new String(charsequence, start, length);
			Log.i("VideoNewsParserImg", new String(charsequence, start, length));
			String[] t = content.split("alt.*./>");
			if(t.length >= 2){
				t[1].replaceAll("<.*.>", "");
				vn.setContent(t[1]);
				String[] temp2 =t[0].split("<img src=\"");
				if(temp2.length == 2){
					String[] temp3 = temp2[1].split("\".*");
					temp3[0].replaceAll("<.*.>", "");
					vn.setImg(getBitMapFromUrl(temp3[0]));
				}
				
				
			}
			else{
				vn.setContent(t[0]);
			}
			
		}
		if(this.in_item && this.in_category){
			vn.setCategory(new String(charsequence, start, length));
		}
		if(this.in_item && this.in_date){
			vn.setPubDate(new String(charsequence, start, length));
		}
	}
	
	public static Bitmap getBitMapFromUrl(String src){
		try {
			URL url = new URL(src);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setDoInput(true);
			connection.connect();
			InputStream input = connection.getInputStream();
			Bitmap myBitmap = BitmapFactory.decodeStream(input);
			return myBitmap;
			
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			return null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			return null;
			
		}
		
		
	}
}
```

Hoffe das hilft weiter um meine Frage zu beantworten.


----------



## Noctarius (16. Jan 2012)

Schau meine Antwort noch mal an und überlege was sie bedeutet.


----------



## Holger (16. Jan 2012)

Ich verstehe deine erste Antwort schon, so ist es nicht. Jedoch wenn ich mich in dem Description Block befinde, wird doch alles was dort drinnen steht in die characters Methode übergeben und dort baue ich mir den String zusammen. Ich verstehe nur nicht warum, die drei Punkte als Delimiters angesehen werden, da ich das nirgends definiert habe.


----------



## Noctarius (16. Jan 2012)

Sammel mal aus Spaß alle String von characters(...) in einem StringBuilder und füge den Inhalt dieses StringBuilders erst in endElement(...) den Elementen hinzu - alternativ musst du den bisherigen String per Getter holen und per Concatination den neuen Teil anhängen.

In XML sind z.B. neue Zeilen auch neue #Text Elemente.


----------



## Holger (16. Jan 2012)

Ok, dank dir. Werde es mal ausprobieren und euch dann informieren was dabei rum gekommen ist.


----------



## Holger (23. Jan 2012)

Noctarius danke für deinen Tipp. Hat funktioniert, lag anscheinend daran das er durch die drei Punkte eine neue charsequence daraus gemacht hat!


----------



## Noctarius (23. Jan 2012)

Ok das kannte ich auch noch nicht, normal sind es Zeilenumbrüche und Tablulatoren


----------



## Holger (23. Jan 2012)

Hatte ich auch gedacht, konnte aber auch nirgendwo eine Beschreibung im Internet finden, was die characters-Methode beim SAX-Parser als Delimiter verwendet. Von daher habe ich mal jeden einzelnen durchlauf der Characters-Methode printen lassen. Und siehe da er trennt die characters nach den (...).


----------



## Noctarius (23. Jan 2012)

Das darf der Sax-Parser frei entscheiden. Wenn du z.B. ein Document aus dem Internet schon beim Runterladen in den Parser schickst, kann er (weil nicht mehr Daten zur Verfügung stehen) auch noch eher abbrechen. Die characters(...) Methode ist explizit mit dem Hinweis versehen, dass sie mehrfach aufgerufen werden kann und Daten aggregiert werden müssen.



> Application writers may override this method to take specific actions for each chunk of character data (such as adding the data to a node or buffer, or printing it to a file).


----------

