Java XML SAX Parser

Um mit Java eine XML Datei zu parsen, empfehle ich einen SAX Parser, da dieser schneller ist als ein DOM Parser. Die Implementierung eines SAX Parsers in Java ist einfach. Man muss nur eine routinemäßige Initialisierung vornehmen und einen eigenen Handler schreiben. Wie das funktioniert, zeigt mein nachfolgendes Code-Beispiel. Ich erkläre ebenfalls, wie man den SAX Parser in Google Android verwenden kann!

XML-Datei

Ich möchte gerne alle Apfelsorten aus der Datei apples.xml auslesen:

apples.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="UTF-8"?>
<root>
	<cultivar>
		<name>Golden Delicious</name>
	</cultivar>
	<cultivar>
		<name>Granny Smith</name>
	</cultivar>	
	<cultivar>
		<name>Idared</name>
	</cultivar>	
		<name>Fuji</name>
	<cultivar>
		<name>Ginger Gold</name>
	</cultivar>
	<cultivar>
		<name>McIntosh</name>
	</cultivar>
	<cultivar>
		<name>Northern Spy</name>
	</cultivar>
	<cultivar>
		<name>Pink Pearl</name>
	</cultivar>
	<cultivar>
		<name>Pinova</name>
	</cultivar>
	<cultivar>
		<name>Red Delicious</name>
	</cultivar>
	<cultivar>
		<name>Spitzenberg</name>
	</cultivar>		
	<cultivar>
		<name>Summerfree</name>
	</cultivar>
	<cultivar>
		<name>SweeTango</name>
	</cultivar>
</root>

Um mein Ziel zu erreichen, muss mein SAX-Parser immer dann, wenn ein öffnendes name-Tag gefunden wird, anfangen alle nachfolgenden Zeichen zu puffern. Die Pufferung muss beendet werden, sobald ein schließendes name-Tag gefunden wird. Der Inhalt des Puffers ist dann mein Ergebnis, welches ich in einer ArrayList aufbewahren möchte.

Code:

Main.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package myjaxparser;
 
import java.io.File;
import java.util.ArrayList;
 
public class Main
{
 
  public static void main(String[] args)
  {
    ArrayList<String> appleCultivars = null;
    File file = new File("apples.xml");
    // Parse apples.xml
    try
    {
      MySaxParser parser = new MySaxParser(file);
      parser.parse();
      appleCultivars = parser.getAppleCultivars();
      // Print results
      for (int i = 0; i < appleCultivars.size(); i++)
      {
        System.out.println(appleCultivars.get(i));
      }
    }
    catch (Exception ex)
    {
      System.out.println("Another exciting error occured: " + ex.getLocalizedMessage());
    }
  }
}

MySaxParser.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package myjaxparser;
 
import java.io.File;
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;
 
public class MySaxParser
{
  private URL url;
  private ArrayList<String> appleCultivars;
 
  public MySaxParser()
  {
    super();
  }
 
  public MySaxParser(File file) throws MalformedURLException
  {
    this.url = file.toURI().toURL();
  }
 
  public void parse() throws ParserConfigurationException, SAXException, IOException
  {
    // Initialize SAX Parser:
    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser parser = factory.newSAXParser();
    XMLReader reader = parser.getXMLReader();
    // Create SAX Handler:
    MySaxHandler handler = new MySaxHandler();
    reader.setContentHandler(handler);
    // Parse XML file:
    InputSource input = new InputSource(url.openStream());
    reader.parse(input);
    // Get the result:
    this.appleCultivars = handler.getAppleCultivars();
  }
 
  public ArrayList<String> getAppleCultivars()
  {
    return this.appleCultivars;
  }
}

MySaxHandler.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package myjaxparser;
 
import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
public class MySaxHandler extends DefaultHandler
{
 
  private StringBuffer buffer;
  private boolean buffering;
  private ArrayList<String> appleCultivars;
 
  public MySaxHandler()
  {
    this.buffer = null;
    this.buffering = false;
    appleCultivars = new ArrayList<String>();
  }
 
  @Override
  public void startDocument() throws SAXException
  {
    this.buffer = new StringBuffer("");
  }
 
  @Override
  public void startElement(String namespaceURI, String localName, String tagName, Attributes attributes) throws SAXException
  {
    String tag = tagName;
    if (tag.equals("name"))
    {
      this.buffering = true;
    }
  }
 
  @Override
  public void endElement(String namespaceURI, String localName, String tagName) throws SAXException
  {
    String tag = tagName;
    String tagValue = null;
 
    if (tag.equals("name"))
    {
      tagValue = this.buffer.toString();
      this.buffering = false;
      this.buffer = new StringBuffer();
    }
 
    parseValue(tagValue);
  }
 
  @Override
  public void characters(char chars[], int start, int length)
  {
    if (this.buffering)
    {
      this.buffer = this.buffer.append(chars, start, length);
    }
  }
 
  private void parseValue(String value)
  {
    if (value != null)
    {
      this.appleCultivars.add(value);
    }
  }
 
  public ArrayList<String> getAppleCultivars()
  {
    return this.appleCultivars;
  }
}

Achtung Android!
Für den Einsatz von MySaxHandler.java in Android muss man String tag = tagName; gegen String tag = localName; austauschen. Das ist zwar ziemlich unlogisch, jedoch hat das Code-Beispiel nur so bei mir funktioniert (getestet mit Google Android 2.1).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.