您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何使用SAX方式解析XML文件,代碼簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
Java SAX解析機制為我們提供了一系列的API來處理XML文件,SAX解析和DOM解析方式不太一樣,它并不是將XML文件內容一次性全部加載,而是連續的部分加載。
javax.xml.parsers.SAXParser
類提供了一些函數,采用事件處理方式解析XML文檔,這個類實現了XMLReader接口,提供了重載的parse()方法從File,InputStream,SAX InputSource和URI字符串中讀取XML文檔。
實際的XML解析工作由Handler類來完成,我們需要創建自己的Handler類,這就需要我們實現org.xml.sax.ContentHandler
接口。這個接口中包含當事件發生時接收通知的回調方法,例如 StartDocument, EndDocument, StartElement, EndElement, CharacterData等等。
org.xml.sax.helpers.DefaultHandler
提供了ContentHandler接口的默認實現,因此我們可以繼承該類實現自己的處理類。繼承這個類是明智的選擇,因為我們可能只需要實現一些方法。繼承這個類可以保證代碼的簡潔和可維護性。
下面是我們要解析的XML文檔:
employees.xml
<?xml version="1.0" encoding="UTF-8"?><Employees> <Employee id="1"> <age>29</age> <name>Pankaj</name> <gender>Male</gender> <role>Java Developer</role> </Employee> <Employee id="2"> <age>35</age> <name>Lisa</name> <gender>Female</gender> <role>CEO</role> </Employee> <Employee id="3"> <age>40</age> <name>Tom</name> <gender>Male</gender> <role>Manager</role> </Employee> <Employee id="4"> <age>25</age> <name>Meghna</name> <gender>Female</gender> <role>Manager</role> </Employee></Employees>
該XML文件內容存放一些員工的信息,每個員工包含id屬性和age, name, gender,role字段。
我們將使用SAX解析機制處理XML文件并創建員工對象列表。
我們使用Employee類抽象員工的信息:Employee.java
package com.journaldev.xml;public class Employee { private int id; private String name; private String gender; private int age; private String role; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } @Override public String toString() { return "Employee:: ID="+this.id+" Name=" + this.name + " Age=" + this.age + " Gender=" + this.gender + " Role=" + this.role; } }
接著繼承DefaultHandler類創建自己的Handler類MyHandler.java
package com.journaldev.xml.sax; import java.util.ArrayList; import java.util.List; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import com.journaldev.xml.Employee; public class MyHandler extends DefaultHandler { //List to hold Employees object private List<Employee> empList = null; private Employee emp = null; //getter method for employee list public List<Employee> getEmpList() { return empList; } boolean bAge = false; boolean bName = false; boolean bGender = false; boolean bRole = false; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("Employee")) { //create a new Employee and put it in Map String id = attributes.getValue("id"); //initialize Employee object and set id attribute emp = new Employee(); emp.setId(Integer.parseInt(id)); //initialize list if (empList == null) empList = new ArrayList<>(); } else if (qName.equalsIgnoreCase("name")) { //set boolean values for fields, will be used in setting Employee variables bName = true; } else if (qName.equalsIgnoreCase("age")) { bAge = true; } else if (qName.equalsIgnoreCase("gender")) { bGender = true; } else if (qName.equalsIgnoreCase("role")) { bRole = true; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase("Employee")) { //add Employee object to list empList.add(emp); } } @Override public void characters(char ch[], int start, int length) throws SAXException { if (bAge) { //age element, set Employee age emp.setAge(Integer.parseInt(new String(ch, start, length))); bAge = false; } else if (bName) { emp.setName(new String(ch, start, length)); bName = false; } else if (bRole) { emp.setRole(new String(ch, start, length)); bRole = false; } else if (bGender) { emp.setGender(new String(ch, start, length)); bGender = false; } } }
MyHandler類持有一個存放Employee對象的List引用,它只有一個對應的getter方法。Employee對象在事件處理函數中被添加到List對象,在MyHandler類中還定義了Employee對象和它的幾個字段相關的boolean類型變量用于創建Employee對象,當Employee對象的所有屬性都被設置時,它就會被添加到list中。
我們重寫了幾個重要的方法startElement(), endElement() 和characters().
當SAXParser 開始解析文檔時遇到元素的開始標簽時,startElement() 方法就會被調用,我們重寫了這個方法,使用boolean類型變量來區分元素類別。我們也是在該方法中,當Employee 標簽開始時創建Employee 對象。
當SAXParser遇到元素中的字符串數據時characters()方法會被調用,我們使用boolean類型字段為Employee對象的屬性進行賦值。
endElement()方法則會在SAXParser 遇到XML結束標簽時會被調用,在這里我們將Employee對象添加到List對象中。
在下面的測試程序中,我們使用MyHandler解析XML文檔生成存放Employee 對象List。
XMLParserSAX.java
package com.journaldev.xml.sax; import java.io.File; import java.io.IOException; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; import com.journaldev.xml.Employee; public class XMLParserSAX { public static void main(String[] args) { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); try { SAXParser saxParser = saxParserFactory.newSAXParser(); MyHandler handler = new MyHandler(); saxParser.parse(new File("/Users/pankaj/employees.xml"), handler); //Get Employees list List<Employee> empList = handler.getEmpList(); //print employee information for(Employee emp : empList) System.out.println(emp); } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); } } }
運行程序輸出:
Employee:: ID=1 Name=Pankaj Age=29 Gender=Male Role=Java DeveloperEmployee:: ID=2 Name=Lisa Age=35 Gender=Female Role=CEOEmployee:: ID=3 Name=Tom Age=40 Gender=Male Role=ManagerEmployee:: ID=4 Name=Meghna Age=25 Gender=Female Role=Manager
SAXParserFactory 類提供了工廠方法來獲取SAXParser 實例,在調用 SAXParser對象的parse方法時傳入Handler對象來處理回調事件。SAXParser解析機制剛開始接觸時有點復雜,但是當你致力于處理大型的XML文檔時,它比DOM解析提供了更有效的解析機制。
原文地址:http://www.php.cn/
Java SAX解析機制為我們提供了一系列的API來處理XML文件,SAX解析和DOM解析方式不太一樣,它并不是將XML文件內容一次性全部加載,而是連續的部分加載。
javax.xml.parsers.SAXParser
類提供了一些函數,采用事件處理方式解析XML文檔,這個類實現了XMLReader接口,提供了重載的parse()方法從File,InputStream,SAX InputSource和URI字符串中讀取XML文檔。
實際的XML解析工作由Handler類來完成,我們需要創建自己的Handler類,這就需要我們實現org.xml.sax.ContentHandler
接口。這個接口中包含當事件發生時接收通知的回調方法,例如 StartDocument, EndDocument, StartElement, EndElement, CharacterData等等。
org.xml.sax.helpers.DefaultHandler
提供了ContentHandler接口的默認實現,因此我們可以繼承該類實現自己的處理類。繼承這個類是明智的選擇,因為我們可能只需要實現一些方法。繼承這個類可以保證代碼的簡潔和可維護性。
下面是我們要解析的XML文檔:
employees.xml
<?xml version="1.0" encoding="UTF-8"?><Employees> <Employee id="1"> <age>29</age> <name>Pankaj</name> <gender>Male</gender> <role>Java Developer</role> </Employee> <Employee id="2"> <age>35</age> <name>Lisa</name> <gender>Female</gender> <role>CEO</role> </Employee> <Employee id="3"> <age>40</age> <name>Tom</name> <gender>Male</gender> <role>Manager</role> </Employee> <Employee id="4"> <age>25</age> <name>Meghna</name> <gender>Female</gender> <role>Manager</role> </Employee></Employees>
該XML文件內容存放一些員工的信息,每個員工包含id屬性和age, name, gender,role字段。
我們將使用SAX解析機制處理XML文件并創建員工對象列表。
我們使用Employee類抽象員工的信息:Employee.java
package com.journaldev.xml;public class Employee { private int id; private String name; private String gender; private int age; private String role; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } @Override public String toString() { return "Employee:: ID="+this.id+" Name=" + this.name + " Age=" + this.age + " Gender=" + this.gender + " Role=" + this.role; } }
接著繼承DefaultHandler類創建自己的Handler類MyHandler.java
package com.journaldev.xml.sax; import java.util.ArrayList; import java.util.List; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import com.journaldev.xml.Employee; public class MyHandler extends DefaultHandler { //List to hold Employees object private List<Employee> empList = null; private Employee emp = null; //getter method for employee list public List<Employee> getEmpList() { return empList; } boolean bAge = false; boolean bName = false; boolean bGender = false; boolean bRole = false; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("Employee")) { //create a new Employee and put it in Map String id = attributes.getValue("id"); //initialize Employee object and set id attribute emp = new Employee(); emp.setId(Integer.parseInt(id)); //initialize list if (empList == null) empList = new ArrayList<>(); } else if (qName.equalsIgnoreCase("name")) { //set boolean values for fields, will be used in setting Employee variables bName = true; } else if (qName.equalsIgnoreCase("age")) { bAge = true; } else if (qName.equalsIgnoreCase("gender")) { bGender = true; } else if (qName.equalsIgnoreCase("role")) { bRole = true; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase("Employee")) { //add Employee object to list empList.add(emp); } } @Override public void characters(char ch[], int start, int length) throws SAXException { if (bAge) { //age element, set Employee age emp.setAge(Integer.parseInt(new String(ch, start, length))); bAge = false; } else if (bName) { emp.setName(new String(ch, start, length)); bName = false; } else if (bRole) { emp.setRole(new String(ch, start, length)); bRole = false; } else if (bGender) { emp.setGender(new String(ch, start, length)); bGender = false; } } }
MyHandler類持有一個存放Employee對象的List引用,它只有一個對應的getter方法。Employee對象在事件處理函數中被添加到List對象,在MyHandler類中還定義了Employee對象和它的幾個字段相關的boolean類型變量用于創建Employee對象,當Employee對象的所有屬性都被設置時,它就會被添加到list中。
我們重寫了幾個重要的方法startElement(), endElement() 和characters().
當SAXParser 開始解析文檔時遇到元素的開始標簽時,startElement() 方法就會被調用,我們重寫了這個方法,使用boolean類型變量來區分元素類別。我們也是在該方法中,當Employee 標簽開始時創建Employee 對象。
當SAXParser遇到元素中的字符串數據時characters()方法會被調用,我們使用boolean類型字段為Employee對象的屬性進行賦值。
endElement()方法則會在SAXParser 遇到XML結束標簽時會被調用,在這里我們將Employee對象添加到List對象中。
在下面的測試程序中,我們使用MyHandler解析XML文檔生成存放Employee 對象List。
XMLParserSAX.java
package com.journaldev.xml.sax; import java.io.File; import java.io.IOException; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; import com.journaldev.xml.Employee; public class XMLParserSAX { public static void main(String[] args) { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); try { SAXParser saxParser = saxParserFactory.newSAXParser(); MyHandler handler = new MyHandler(); saxParser.parse(new File("/Users/pankaj/employees.xml"), handler); //Get Employees list List<Employee> empList = handler.getEmpList(); //print employee information for(Employee emp : empList) System.out.println(emp); } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); } } }
運行程序輸出:
Employee:: ID=1 Name=Pankaj Age=29 Gender=Male Role=Java DeveloperEmployee:: ID=2 Name=Lisa Age=35 Gender=Female Role=CEOEmployee:: ID=3 Name=Tom Age=40 Gender=Male Role=ManagerEmployee:: ID=4 Name=Meghna Age=25 Gender=Female Role=Manager
SAXParserFactory 類提供了工廠方法來獲取SAXParser 實例,在調用 SAXParser對象的parse方法時傳入Handler對象來處理回調事件。SAXParser解析機制剛開始接觸時有點復雜,但是當你致力于處理大型的XML文檔時,它比DOM解析提供了更有效的解析機制。
上述內容就是如何使用SAX方式解析XML文件,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。