This example will show you how to use SAXParserFactory and SAXParser to parse an XML file from a URL. All above class is included in package javax.xml.parsers
If you can not watch the above video, you can see it on the youtube URL https://youtu.be/_Vlwyryv0nM
- This example is based on Android Parse Xml Use XmlPullParser Example. It just adds a button.
- When clicking this button, it will read the XML data from the same URL and use the SAX parser to parse it and display the parse result in the bottom text view.
1. SAX Parser Working Diagram.
- SAX parser is something different from XmlPullParser.
- It will parse the XML document from the first element to the last element in order.
- To use sax parser, you need to create a custom content handler class. This class should extend the class org.xml.sax.helpers.DefaultHandler.
- You should override the methods in the DefaultHandler class that you need. Such as startElement, endElement, characters etc. Those methods are easy to understand according to the method name.
- In those override methods, you can write java code to save related node names and node text values.
- You can also create an error handler, DTD handler, etc for different usage.
2. SAX Parser Java Code Example.
- Below is the example source files list.
D:\WORK\DEV2QA.COM-EXAMPLE-CODE\ANDROIDEXAMPLEPROJECT\EXAMPLE\APP\SRC\MAIN\JAVA\COM\DEV2QA\EXAMPLE\XML │ SaxParserHandler.java │ XmlPullParserActivity.java │ └─dto UserInfoDTO.java
- Based on the previous example Android Parse Xml Use XmlPullParser Example, you just need to add the below code in your activity’s onCreate method.
// When click parse xml use sax parser button. parseXmlUseSaxButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Create a OkHttpClient request builder. Request.Builder builder = new Request.Builder(); // Set xml file url. builder = builder.url(xmlFileUrl); // Build http request. Request request = builder.build(); // Create a OkHttp3 Call object. Call call = okHttpClient.newCall(request); // Execute the get XML file request asynchronously in an automated child thread. call.enqueue(new Callback() { // If http get request fail. @Override public void onFailure(Call call, IOException e) { sendXmlParseResultToActivityHandler(e.getMessage()); } // If http get request success. @Override public void onResponse(Call call, Response response) throws IOException { // If server response success. if(response.isSuccessful()) { // Get response return xml string. String resultXml = response.body().string(); // Parse the xml string. String xmlParseResult = parseXmlUseSaxParser(resultXml); // Send a message to activity main thread Handler to show the XML parsed result. sendXmlParseResultToActivityHandler(xmlParseResult); } } }); } });
2.1 Parse Xml Use SAX Parser Methods.
- The below method will parse the XML content use the sax parser.
/* Parse xml string use sax parser.Return parsed string. */ private String parseXmlUseSaxParser(String xmlString) { StringBuffer retBuf = new StringBuffer(); try { // Create xml sax parser factory. SAXParserFactory parserFactory = SAXParserFactory.newInstance(); // Create sax parser by factory. SAXParser saxParser = parserFactory.newSAXParser(); // Get xml reader object from sax parser. XMLReader xmlReader = saxParser.getXMLReader(); // Create xml content sax handler. SaxParserHandler xmlDataHandler = new SaxParserHandler(); // Set sax parser handler to xml reader. xmlReader.setContentHandler(xmlDataHandler); // Create a new StringReader. StringReader xmlStringReader = new StringReader(xmlString); // Get input source from string reader. InputSource inputSource = new InputSource(xmlStringReader); // Parse xml use sax parser. xmlReader.parse(inputSource); // Get parsed out user info dto list after sax parse. List<UserInfoDTO> userInfoDtoList = xmlDataHandler.getUserInfoDTOList(); // Loop the list, build formatted string to return. for(UserInfoDTO userInfoDto : userInfoDtoList) { retBuf.append("user = " + userInfoDto.getUser() + "\r\n\r\n"); retBuf.append("email = " + userInfoDto.getEmail() + "\r\n\r\n"); retBuf.append("title = " + userInfoDto.getTitle() + "\r\n\r\n"); retBuf.append("**************************************\r\n\r\n"); } }catch(Exception ex) { // Add error message. retBuf.append(ex.getMessage()); }finally { return retBuf.toString(); } }
2.2 Custom SAX Parser Content Handler.
- This is the custom content handler which process XML element parsing and get related node name and text value.
- It’s userInfoDTOList variable is used to save parsed out user info data list.
- SaxParserHandler.java
package com.dev2qa.example.xml; import com.dev2qa.example.xml.dto.UserInfoDTO; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import java.util.ArrayList; import java.util.List; public class SaxParserHandler extends DefaultHandler { // Used to store parsed out UserInfoDTO list. private List<UserInfoDTO> userInfoDTOList = null; // Record current parse xml element node name. private String currNodeName = ""; // Save current parsed out UserInfoDTO. private UserInfoDTO currUserInfoDto = null; public List<UserInfoDTO> getUserInfoDTOList() { if(userInfoDTOList == null) { userInfoDTOList = new ArrayList<UserInfoDTO>(); } return userInfoDTOList; } public void setUserInfoDTOList(List<UserInfoDTO> userInfoDTOList) { this.userInfoDTOList = userInfoDTOList; } // This method is invoked when start parse xml element node use sax parser. @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // Record current paring xml element node name. currNodeName = localName; } // When sax parse xml element node finished, invoke this method. @Override public void endElement(String uri, String localName, String qName) throws SAXException { // If this is the end of employee xml element. if("employee".equalsIgnoreCase(localName)) { // Add current user info dto to userInfoDto list. getUserInfoDTOList().add(currUserInfoDto); // Set current user info dto to null. currUserInfoDto = null; } } // This method is invoked when sax parser parse xml node text. @Override public void characters(char[] ch, int start, int length) throws SAXException { // First get the text value. StringBuffer strBuf = new StringBuffer(); if(length > 0) { strBuf.append(ch, start, length); } // Remove node text beginning and ending white space characters ( \r\n etc. ). String nodeText = strBuf.toString().trim(); if("employee".equalsIgnoreCase(currNodeName)) { // If current node is employee then create a new UserInfoDTO instance. currUserInfoDto = new UserInfoDTO(); }else if("user".equalsIgnoreCase(currNodeName)) { if(nodeText.length() > 0) { // Set user data. currUserInfoDto.setUser(nodeText); } }else if("email".equalsIgnoreCase(currNodeName)) { if(nodeText.length() > 0) { // Set email data. currUserInfoDto.setEmail(nodeText); } }else if("title".equalsIgnoreCase(currNodeName)) { if(nodeText.length() > 0) { // Set title data. currUserInfoDto.setTitle(nodeText); } } } }
2.3 User Info DTO.
- This DTO is used to save the parsed-out user info.
- UserInfoDTO.java
package com.dev2qa.example.xml.dto; import java.io.Serializable; public class UserInfoDTO implements Serializable { private String user = ""; private String email = ""; private String title = ""; public String getUser() { return user; } public void setUser(String user) { this.user = user; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }