Core Java
XML parsing using SaxParser with complete code
SAX parser use callback function (org.xml.sax.helpers.DefaultHandler) to informs clients of the XML document structure. You should extend DefaultHandler and override few methods to achieve xml parsing.
The methods to override are
- 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.
The following example demonstrates the uses of DefaultHandler to parse and XML document. It performs mapping of xml to model class and generate list of objects.
Sample XML Document :
<?xml version="1.0" encoding="UTF-8"?> <catalog> <book id="001" lang="ENG"> <isbn>23-34-42-3</isbn> <regDate>1990-05-24</regDate> <title>Operating Systems</title> <publisher country="USA">Pearson</publisher> <price>400</price> <authors> <author>Ganesh Tiwari</author> </authors> </book> <book id="002"> <isbn>24-300-042-3</isbn> <regDate>1995-05-12</regDate> <title>Distributed Systems</title> <publisher country="Nepal">Ekata</publisher> <price>500</price> <authors> <author>Mahesh Poudel</author> <author>Bikram Adhikari</author> <author>Ramesh Poudel</author> </authors> </book> </catalog>
Model Class for Book Object for Mapping xml to object
/** * Book class stores book information, after parsing the xml * @author Ganesh Tiwari */ public class Book { String lang; String title; String id; String isbn; Date regDate; String publisher; int price; List<String> authors; public Book(){ authors=new ArrayList<String>(); } //getters and setters }
Java Code for XML Parsing (Sax) :
import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; 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.helpers.DefaultHandler; public class MySaxParser extends DefaultHandler { List<Book> bookL; String bookXmlFileName; String tmpValue; Book bookTmp; SimpleDateFormat sdf= new SimpleDateFormat("yy-MM-dd"); public MySaxParser(String bookXmlFileName) { this.bookXmlFileName = bookXmlFileName; bookL = new ArrayList<Book>(); parseDocument(); printDatas(); } private void parseDocument() { // parse SAXParserFactory factory = SAXParserFactory.newInstance(); try { SAXParser parser = factory.newSAXParser(); parser.parse(bookXmlFileName, this); } catch (ParserConfigurationException e) { System.out.println("ParserConfig error"); } catch (SAXException e) { System.out.println("SAXException : xml not well formed"); } catch (IOException e) { System.out.println("IO error"); } } private void printDatas() { // System.out.println(bookL.size()); for (Book tmpB : bookL) { System.out.println(tmpB.toString()); } } @Override public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException { // if current element is book , create new book // clear tmpValue on start of element if (elementName.equalsIgnoreCase("book")) { bookTmp = new Book(); bookTmp.setId(attributes.getValue("id")); bookTmp.setLang(attributes.getValue("lang")); } // if current element is publisher if (elementName.equalsIgnoreCase("publisher")) { bookTmp.setPublisher(attributes.getValue("country")); } } @Override public void endElement(String s, String s1, String element) throws SAXException { // if end of book element add to list if (element.equals("book")) { bookL.add(bookTmp); } if (element.equalsIgnoreCase("isbn")) { bookTmp.setIsbn(tmpValue); } if (element.equalsIgnoreCase("title")) { bookTmp.setTitle(tmpValue); } if(element.equalsIgnoreCase("author")){ bookTmp.getAuthors().add(tmpValue); } if(element.equalsIgnoreCase("price")){ bookTmp.setPrice(Integer.parseInt(tmpValue)); } if(element.equalsIgnoreCase("regDate")){ try { bookTmp.setRegDate(sdf.parse(tmpValue)); } catch (ParseException e) { System.out.println("date parsing error"); } } } @Override public void characters(char[] ac, int i, int j) throws SAXException { tmpValue = new String(ac, i, j); } public static void main(String[] args) { new MySaxParser("catalog.xml"); } }
Output of Parsing :
Book [lang=ENG, title=Operating Systems, id=001, isbn=23-34-42-3, regDate=Thu May 24 00:00:00 NPT 1990, publisher=USA, price=400, authors=[Ganesh Tiwari]] Book [lang=null, title=Distributed Systems, id=002, isbn=24-300-042-3, regDate=Fri May 12 00:00:00 NPT 1995, publisher=Nepal, price=500, authors=[Mahesh Poudel, Bikram Adhikari, Ramesh Poudel]]
Reference: XML parsing using SaxParser with complete code from our JCG partner Ganesh Tiwari at the GT’s Blog .
A very nice example for SAX starter.
Thanks!
I got a problem while trying this code.
It said : “Exception in thread “main” java.lang.NullPointerException”.
What does it mean?
Thanks
It means you have some blank edit text in your App..Check it
You have excellent work dude. XML parsing is bit tricky so trying various approach will help your knowledge. I would recommend this XML Parsing with Another fine approach with step to step explanation
and how do you get the authors??
Nice writing. It would be better if the toString() method were not missing in the Book class.
What if I have 2 elements with same name?
Thank you for your great post. Only one thing i want to use SAX to read only part of the file at first, then when user scrolls down i want to use the next part and so on… How can i achieve this?
@
You might take the below approach:
1. Add the following in the Book Class:
private List authors;
and generate the getter and setter for this field
public List getAuthors() {
return authors;
}
public void setAuthors(List authors) {
this.authors = authors;
}
2. Declare a tempAuthor as list in the Parser class , like– List tempAuthor;
3.Inside startElement method have the below lines of code
if(elementName.equalsIgnoreCase(“authors”)){
tempAuthor = new ArrayList();
}
4.Inside the endElement method add the following lines
if(element.equalsIgnoreCase(“authors”)){
tempBook.setAuthors(tempAuthor);
}
if(element.equalsIgnoreCase(“author”)){
tempAuthor.add(tempValue);
}
This will suffice for getting the author.
Hi Folks,
If I have author node like this,
Mahesh Poudel
Bikram Adhikari
Ramesh Poudel
Then how to get list of authors like this [{Rupali: Mahesh Poudel}, {xyz: Bikram Adhikari}].. so on..
Thanks.
Sorry, XML deleted..
XML like this..
< author name=”rupali” > Mahesh Poudel </author>
I want to know how we save this parsed data into database means how can we pass this setter value we is generated by XML parsing in the bean file..
Please Someone find the solution to save this parsed data into database by creating table in database.
okay, from what i can tell, we have only objects, in this scenario a book object. You can first parse all the elements in the xml, then do a for each statement to insert every data you have saved in a list to a database.
// create a database table here defining your values es name, author etc.
for (Book b : bookL){
// get attributes from b
// insert attributes into database using sql statement
}
CAnt go into details but i think this approach might work
Thanks
it’s good example !!!.
Hi Folks,
If I have author node like this,
>authors<
>author name=”rupali” < Mahesh>/author<
>author name=”xyz” <Bikram >/author<
&/gt;authors<
Then how to get list of authors like this [{rupali: Mahesh, xyz: Bikram} .. {….}] so on..
Thanks.
Thanks for your usefoul example.
In your example, how can I obtain value “Ekata” from tag and save it in the Book class?
String publisher contains the attribute of tag publisher, but how can save also the value “Ekata” and store it on Book class?
Thankls in advance
Alex
how i can parse the comments in XML file with Saxparser
I have a query here , like if we have the xml file with different tags with different object structure then How to do it? Like for an example as follows: 02 03 04 23-34-42-3 05 1990-05-24 06 Operating Systems 07 Pearson 08 400 09 10 Ganesh Tiwari 11 12 13 14 24-300-042-3 15 1995-05-12 16 Distributed Systems 17 Ekata 18 500 19 20 Mahesh Poudel 21 Bikram Adhikari 22 Ramesh Poudel 23 24 25 My be again inside some tag another child object kind of then how to proceed? I need to store all the details in correct hierarchy… Read more »
Thanks! It worked for me!
How can I read HTML elements present in the XML file i.e. some nodes have tags to represent some data in bold characters and parser is skipping those tags and not reading data under those tags. So how to read those tags as well while parsing the file?