How to read XML file in Java – (SAX Parser)

SAX parser is work differently with DOM parser, it either load any XML document into memory nor create any object representation of the XML document. Instead, the SAX parser use callback function (org.xml.sax.helpers.DefaultHandler) to informs clients of the XML document structure.

SAX Parser is faster and uses less memory than DOM parser.

See following SAX callback methods :

  • startDocument() and endDocument() – Method called at the start and end of an XML document.
  • startElement() and endElement() – Method called at the start and end of a document element.
  • characters() – Method called with the text contents in between the start and end tags of an XML document element.

1. XML file

Create a simple XML file.

<?xml version="1.0"?>
<company>
	<staff>
		<firstname>yong</firstname>
		<lastname>mook kim</lastname>
		<nickname>mkyong</nickname>
		<salary>100000</salary>
	</staff>
	<staff>
		<firstname>low</firstname>
		<lastname>yin fong</lastname>
		<nickname>fong fong</nickname>
		<salary>200000</salary>
	</staff>
</company>

2. Java file

Use SAX parser to parse the XML file.

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
public class ReadXMLFile {
 
   public static void main(String argv[]) {
 
    try {
 
	SAXParserFactory factory = SAXParserFactory.newInstance();
	SAXParser saxParser = factory.newSAXParser();
 
	DefaultHandler handler = new DefaultHandler() {
 
	boolean bfname = false;
	boolean blname = false;
	boolean bnname = false;
	boolean bsalary = false;
 
	public void startElement(String uri, String localName,String qName, 
                Attributes attributes) throws SAXException {
 
		System.out.println("Start Element :" + qName);
 
		if (qName.equalsIgnoreCase("FIRSTNAME")) {
			bfname = true;
		}
 
		if (qName.equalsIgnoreCase("LASTNAME")) {
			blname = true;
		}
 
		if (qName.equalsIgnoreCase("NICKNAME")) {
			bnname = true;
		}
 
		if (qName.equalsIgnoreCase("SALARY")) {
			bsalary = true;
		}
 
	}
 
	public void endElement(String uri, String localName,
		String qName) throws SAXException {
 
		System.out.println("End Element :" + qName);
 
	}
 
	public void characters(char ch[], int start, int length) throws SAXException {
 
		if (bfname) {
			System.out.println("First Name : " + new String(ch, start, length));
			bfname = false;
		}
 
		if (blname) {
			System.out.println("Last Name : " + new String(ch, start, length));
			blname = false;
		}
 
		if (bnname) {
			System.out.println("Nick Name : " + new String(ch, start, length));
			bnname = false;
		}
 
		if (bsalary) {
			System.out.println("Salary : " + new String(ch, start, length));
			bsalary = false;
		}
 
	}
 
     };
 
       saxParser.parse("c:\\file.xml", handler);
 
     } catch (Exception e) {
       e.printStackTrace();
     }
 
   }
 
}

Result

Start Element :company
Start Element :staff
Start Element :firstname
First Name : yong
End Element :firstname
Start Element :lastname
Last Name : mook kim
End Element :lastname
Start Element :nickname
Nick Name : mkyong
End Element :nickname
Start Element :salary
Salary : 100000
End Element :salary
End Element :staff
Start Element :staff
Start Element :firstname
First Name : low
End Element :firstname
Start Element :lastname
Last Name : yin fong
End Element :lastname
Start Element :nickname
Nick Name : fong fong
End Element :nickname
Start Element :salary
Salary : 200000
End Element :salary
End Element :staff
End Element :company
Warning
This example may encounter exceptions for UTF-8 XML file, please read this article about how to read the XML “UTF-8″ file in SAX
Note
You may interest to read this How to read XML file in Java – (DOM Parser)
Tags :

About the Author

mkyong
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

  • Pingback: Service Stock di Java | Start from Bad Coding()

  • Reji

    How can we use this parse to access the set of multiple occurrence of data containing nested records

    Like

    John

    21
    BeerLand

    KIM

    20
    High Spirits

  • Reji

    How can we use this parse to access the set of multiple occurrence of data containing nested records

    Like

    John

    21
    BeerLand

    KIM

    20
    High Spirits

  • sp

    Hi, can some one tell how to handle empty axml tags while parsing ? like or

  • Mal1990

    Hi ,

    I am totally new to java . I need to parse a EDI XML and display its attributes alone text file. The text file should be pipe delimited(|). ie; all the attributes should be separated by | symbol.

    This has to be done using sax parser. Kindly help me on this

  • Mal1990

    Hi ,

    I am totally new to java . I need to parse a EDI XML and display its attributes alone text file. The text file should be pipe delimited(|). ie; all the attributes should be separated by | symbol. Kindly help me on this

  • sony

    too good!!!!!thanks mykong….

  • Quin

    How can you sort the data, for example, if you want to sort by last name element on your xml file, output it out on java, need help.

  • JC

    DOM Parser post helped me alot.
    But I am stuck with 1 thing,could you please suggest which parser to use for redundant tags.eg :-

    empData

    Tom
    25
    English
    French

    Swiss
    25
    English
    German
    French

    Each config can have 1 or more tag and each can have 1 or more tag.With Dom parser,either I am getting only first tag or all for all employees,I want corresponding to each employee.

    Thanks

  • sirj77

    Hey!
    I’ve tried to run this example, but received an error:
    “Error: Could not find or load main class Tasks.XML Parser SAX”
    Could anyone help me?

  • Andres

    Thanks for you post!!!
    it helped me a lot

  • vijaya

    Thanks, it helped me a lot.

  • http://www.mt-portfolio.nl Mark Tielemans

    Bit lame I can’t edit that comment :P.

  • http://www.mt-portfolio.nl Mark Tielemans

    You can keep track of open/closed elements much more gracefully using a Map:

    Map&lt;String, Boolean&gt; elements = new HashMap&lt;String, Boolean&gt;();
    &lt;/pre
     
    onStart:
    &lt;pre lang=&quot;java&quot;&gt;elements.put(qName, true);

    onEnd:

    elements.put(qName, false);

    Nice guide!

    • http://talkwards.com Erik

      Hello!

      Nice guide.

      I had a very simple scenario with XML like:


      This made it possible to just store the opening tag’s gName in a variable and then handle it accordingly in the characters-method:

      class XXX {

      /* Item defined elsewhere */
      private final LinkedList items = new LinkedList();

      private final SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”);

      private final DefaultHandler handler = new DefaultHandler() {

      private Item item;

      private String qName;

      @Override
      public void startElement(
      String uri, String localName,
      String qName, Attributes attributes)
      throws SAXException
      {
      this.qName = qName;
      if (“ROW”.equalsIgnoreCase(qName)) {
      item = new Item();
      }
      }

      @Override
      public void endElement(String uri, String localName, String qName)
      throws SAXException
      {
      if (“ROW”.equalsIgnoreCase(qName) && item != null) {
      items.add(item);
      }
      }

      @Override
      public void characters(char[] ch, int start, int length)
      throws SAXException
      {
      if (item == null)
      return;

      final String string = new String(ch, start, length).trim();

      if (“TITLE”.equalsIgnoreCase(qName)) {
      item.setName(string);
      }
      else if (“LINK”.equalsIgnoreCase(qName)) {
      item.setLink(string);
      }
      else if (“DATE”.equalsIgnoreCase(qName)) {
      try {
      final Date date = dateFormat.parse(string);
      item.setDate(date);
      }
      catch (ParseException pe) {
      pe.printStackTrace(System.err);
      }
      }
      else if (“DESCRIPTION”.equalsIgnoreCase(qName)) {
      item.setDescription(string);
      }
      }

      };
      }

      However, I don’t think it would be too hard to adjust the code to handle sub-items. Unfortunately my implementation doesn’t take that good advantage of the SAX Parsing since it saves all the Item-objects, but at least I’ll only have one set of data, the list of items, instead of also having the DOM-tree.

      One quick fix would be to slap on Observable and have the code notify with the Item instead. Or implement some other handling in the endElement code to avoid putting the items in a list.

      • http://talkwards.com Erik

        You just have to cut and paste the code into an IDE and code format it…

  • http://[email protected] Gubs

    Hi Monk,

    StartElement is not getting called in my sample below code. You have any idea ?
    public class ReadXMLFileUsingSAXParser {

    String fname = null;
    String lname = null;
    String sal = null;

    /**
    * @param args
    * @throws IOException
    */
    public static void main(String[] args) throws IOException {

    SAXParserFactory factory = SAXParserFactory.newInstance();
    try {
    SAXParser parser = factory.newSAXParser();

    DefaultHandler handler = new DefaultHandler();

    parser.parse(“src/main/resources/testSaxParser.xml”, handler);

    } catch (ParserConfigurationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (SAXException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }

    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    if (qName.equalsIgnoreCase(“firstname”)) {
    fname = attributes.getValue(“firstname”);
    System.out.println(“Firstname ” + fname);
    }
    }
    }

    • Nicholas

      hi Gubs,

      i have no idea.

    • http://talkwards.com Erik

      startElement should be inside DefaultHandler… check the code in the article one more time.

  • hendi santika

    I’ve tried the code, but i have a problem here.
    The result is :
    End Element :firstname
    End Element :lastname
    End Element :nickname
    End Element :salary
    End Element :staff
    End Element :firstname
    End Element :lastname
    End Element :nickname
    End Element :salary
    End Element :staff
    End Element :company

    Why does it happen ???

    Thanks

    • Erik Larsson

      I have the same problem, please answer someone!

  • krishnaveni

    Hi.,
    This is really helped me..Thanks a lot for gave me such a nice tutorial…

  • yog

    GREAT WEBSITE.. BEST AND SIMPLE EXAMPLE.
    THNX

    “SAX parser is work differently with DOM parser, it either load any XML document into memory nor create any object representation of the XML document.”

    IT SHOULD BE NEITHER , NOT EITHER.

  • LG

    “it either load any XML document into memory nor create any object representation of the XML document. Instead”
    Are u trying to say neither load any XML document into memory

  • Pingback: Store and reterive .xml file in sqlite database in android : Android Community - For Application Development()