栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 人工智能 > NLP

Java&Xml教程(五)使用SAX方式解析XML文件

NLP 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java&Xml教程(五)使用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

            29        Pankaj        Male        Java Developer                35        Lisa        Female        CEO                40        Tom        Male        Manager                25        Meghna        Female        Manager    

该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 empList = null;        private Employee emp = null;        //getter method for employee list    public List 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 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解析提供了更有效的解析机制。
原文地址:https://www.mshxw.com/

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

            29        Pankaj        Male        Java Developer                35        Lisa        Female        CEO                40        Tom        Male        Manager                25        Meghna        Female        Manager    

该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 empList = null;        private Employee emp = null;        //getter method for employee list    public List 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 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解析提供了更有效的解析机制。

以上就是Java&Xml教程(五)使用SAX方式解析XML文件的内容,更多相关内容请关注PHP中文网(www.kaotop.com)!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/794836.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号