• dom4j解析器 基于dom4j的xpath技术 简单工厂设计模式 分层结构设计思想 SAX解析器 DOM编程


    *1 dom4j解析器
      1)CRUD的含义:CreateReadUpdateDelete增删查改
      2)XML解析器有二类,分别是DOM和SAX(simple Api for xml)。
        a)DOM一次性将整个XML文件读到内存,形成一个倒状的树形结构 
        b)SAX多次将整个XML文件读到内存 
        c)Document对象代表XML文件在内存中的映像 
      3)常用的API如下:
        SAXReader saxReader = new SAXReader(); SAXReader是dom4j的核心类
        Document document = saxReader.read("*.xml")
        Document.getRootElement()
        Element.getName()
        Element.elements():取得该元素下的所有直接子元素 
        Element.elementText():从一个元素导航到另一个元素且取出该元素的文本
        Element.element("车牌")    :从一个元素导航到另一个元素
        Element.attributeValue("出产时间"):取得一个元素对应的属性
        Element.addElement("单价").setText("40"):添加新元素,同时设置该元素文本的值
        OutputFormat format = OutputFormat.createPrettyPrint():使用缩格形式写XML文件
        XMLWriter xmlWriter = new XMLWriter(os,format):构造XML写入器
        xmlWriter.write(document):将内存中的document对象写入硬盘
        firstCarElement.remove(firstCarPriceElement):从直接父元素删除直接子元素
        //firstCarPriceElement.getParent().remove(firstCarPriceElement):从直接父元素删除直接子元素

    package cn.itcast.xml.dom4j;
    
    public class Car implements Comparable<Car>{
        private String band;//车牌
        private String place;//产地
        private String time;//出产时间
        private int price;//单价
        public Car(){}
        public String getBand() {
            return band;
        }
        public void setBand(String band) {
            this.band = band;
        }
        public String getPlace() {
            return place;
        }
        public void setPlace(String place) {
            this.place = place;
        }
        public String getTime() {
            return time;
        }
        public void setTime(String time) {
            this.time = time;
        }
        public int getPrice() {
            return price;
        }
        public void setPrice(int price) {
            this.price = price;
        }
        public int compareTo(Car car) {
            if(this.price<car.getPrice()){
                return 1;
            }else if(this.price>car.getPrice()){
                return -1;
            }else{
                return 0;
            }
        }
    }
    package cn.itcast.xml.dom4j;
    
    import java.io.File;
    import java.util.List;
    
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    //基于DOM4J解析XML文件(read)[dom4j-1.6.1.jar]
    //使用dom4j解析xml文件
    public class Demo1 {
        public static void main(String[] args) throws Exception {
            //创建dom4j解析器
            SAXReader saxReader = new SAXReader();
            //加载需要解析的xml文件
            Document document = saxReader.read(new File("src/cn/itcast/xml/dom4j/car.xml"));
            //取得根元素
            Element rootElement = document.getRootElement();
            //显示根元素的名称
            System.out.println(rootElement.getName());
            //取得根元素下的子元素
            List<Element> elementList = rootElement.elements();
            System.out.println("共有" + elementList.size()+"辆车");
            for(Element e : elementList){
                System.out.println("车牌:" + e.elementText("车牌"));
                System.out.println("产地:" + e.elementText("产地"));
                System.out.println("出产时间:" + e.element("车牌").attributeValue("出产时间"));
                System.out.println("------------------------------");
            }
        }
    }
    package cn.itcast.xml.dom4j;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.OutputFormat;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    import org.junit.Test;
    
    //使用dom4j操作xml文件的cud
    public class Demo2 {
        @Test
        public void create() throws Exception{
            Document document = getDocument();
            Element rootElement = document.getRootElement();
            //取得第一辆汽车
            Element firstCarElement = (Element) rootElement.elements().get(0);
            //添加新元素"单价",并设置文本为30
            firstCarElement.addElement("单价").setText("40");
            //将内存中的xml文件写到硬盘中
            write2xml(document);
        }
        private void write2xml(Document document) throws Exception {
            OutputFormat format = OutputFormat.createPrettyPrint();
            OutputStream os = new FileOutputStream("src/cn/itcast/xml/dom4j/car.xml");
            XMLWriter xmlWriter = new XMLWriter(os,format);
            xmlWriter.write(document);
            xmlWriter.close();
        }
        private Document getDocument() throws Exception {
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new File("src/cn/itcast/xml/dom4j/car.xml"));
            return document;
        }
        @Test
        public void update() throws Exception{
            Document document = getDocument();
            Element rootElement = document.getRootElement();
            Element firstCarElement = (Element) rootElement.elements().get(0);
            firstCarElement.element("单价").setText("60");
            write2xml(document);
        }
        @Test
        public void delete() throws Exception{
            Document document = getDocument();
            Element rootElement = document.getRootElement();
            Element firstCarElement = (Element) rootElement.elements().get(0);
            Element firstCarPriceElement = firstCarElement.element("单价");
            firstCarElement.remove(firstCarPriceElement);
            //firstCarPriceElement.getParent().remove(firstCarPriceElement);
            write2xml(document);
        }
    }
    package cn.itcast.xml.dom4j;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    //课堂练习(将car.xml文件中的所有car元素解析出存入集合,并按照单价对集合中的元素降序后输出)
    public class Demo3 {
        public static void main(String[] args) throws Exception {
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new File("src/cn/itcast/xml/dom4j/car.xml"));
            List<Element> elementList = document.getRootElement().elements();
            List<Car> carList = new ArrayList<Car>();
            for(Element e : elementList){
                Car car = new Car();
                car.setBand(e.elementText("车牌"));
                car.setPlace(e.elementText("产地"));
                car.setTime(e.element("车牌").attributeValue("出产时间"));
                car.setPrice(Integer.parseInt(e.elementText("单价")));
                carList.add(car);
            }
            //System.out.println("按单价排序前:");
            //show(carList);
            System.out.println("按单价排序后:");
            sortByPriceDesc(carList);
        }
        public static void sortByPriceDesc(List<Car> carList) {
            Collections.sort(carList);
            show(carList);
        }
        public static void show(List<Car> carList){
            if(carList!=null && carList.size()>0){
                for(Car car : carList){
                    System.out.print("车牌:"+car.getBand()+"	");
                    System.out.print("产地:"+car.getPlace()+"	");
                    System.out.print("单价:"+car.getPrice()+"	");
                    System.out.println("出产时间:"+car.getTime());
                }
            }
        }
    }
    package cn.itcast.xml.dom4j;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import java.util.List;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.dom4j.io.OutputFormat;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    
    //使用dom4j其它的API
    public class Demo4 {
        public static void main(String[] args) throws Exception {
            
            /*String->XML
            String text = "<root><res>这是根元素</res></root>";
            Document document = DocumentHelper.parseText(text);
            OutputFormat format = OutputFormat.createPrettyPrint();
            OutputStream os = new FileOutputStream("src/cn/itcast/xml/dom4j/string2xml.xml");
            XMLWriter xmlWriter = new XMLWriter(os,format);
            xmlWriter.write(document);
            xmlWriter.close();
            */
            
            /*创建空XML文件
             Document document = DocumentHelper.createDocument();
            document.addElement("root").setText("这是根元素");
            OutputFormat format = OutputFormat.createPrettyPrint();
            OutputStream os = new FileOutputStream("src/cn/itcast/xml/dom4j/empty.xml");
            XMLWriter xmlWriter = new XMLWriter(os,format);
            xmlWriter.write(document);
            xmlWriter.close();
            */
            
            /*指定插入次序,默认插入到最后
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new File("src/cn/itcast/xml/dom4j/car.xml"));
            List<Element> elementList = document.getRootElement().elements();
            Element newCarElement = DocumentHelper.createElement("汽车");
            newCarElement.setText("这是我的汽车");
            elementList.add(1,newCarElement);
            OutputFormat format = OutputFormat.createPrettyPrint();
            OutputStream os = new FileOutputStream("src/cn/itcast/xml/dom4j/car.xml");
            XMLWriter xmlWriter = new XMLWriter(os,format);
            xmlWriter.write(document);
            xmlWriter.close();
            */
            
            //XML->String
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new File("src/cn/itcast/xml/dom4j/car.xml"));
            Element rootElement = document.getRootElement();
            Element firstCarElement = (Element) rootElement.elements().get(0);
            String xml = firstCarElement.asXML();
            System.out.println(xml);
        }
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <车辆清单> 
      <汽车> 
        <车牌 出产时间="2010年">奥迪</车牌>  
        <产地>北京</产地>  
        <单价>30</单价> 
      </汽车>  
      <汽车> 
        <车牌 出产时间="2011年">本田</车牌>  
        <产地>广州</产地>  
        <单价>60</单价> 
      </汽车> 
    </车辆清单>
    <?xml version="1.0" encoding="UTF-8"?>
    
    <root>这是根元素</root>
    <?xml version="1.0" encoding="UTF-8"?>
    <root>
      <res>这是根元素</res>
    </root>

    *2 基于dom4j的xpath技术
      1)能够在xml文件中,快速定位需要元素,无需从根元素一个一个的导航到需要的子元素
        Document.selectNodes():取得所有符合xpath格式的元素
        Document.selectSingleNode():取得所有符合xpath格式的元素的第一个元素
        Node类型是Element/Text/Attribute/Document/...类型的父接口

    package cn.itcast.xml.xpath;
    
    import java.io.File;
    import java.util.List;
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    //使用Xpath,取得第二辆汽车的产地[dom4j-1.6.1.jar和jaxen-1.1-beta-6.jar]
    public class Demo1 {
        public static void main(String[] args) throws Exception {
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File("src/cn/itcast/xml/xpath/car.xml"));
            String xpath = "//单价";
            Element element = (Element) document.selectSingleNode(xpath);
            System.out.println("第一辆汽车的单价是:" + element.getText());
            
            //List<Element> elementList = document.selectNodes(xpath);
            //System.out.println("第二辆汽车的单价是:" + elementList.get(1).getText());
        }
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <车辆清单> 
      <汽车> 
        <车牌 出产时间="2010年">奥迪</车牌>  
        <产地>北京</产地>  
        <单价>30</单价> 
      </汽车>  
      <汽车> 
        <车牌 出产时间="2011年">本田</车牌>  
        <产地>广州</产地>  
        <单价>60</单价> 
      </汽车> 
    </车辆清单>
    package cn.itcast.xml.xpath;
    
    import java.io.File;
    import java.util.Scanner;
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    //使用Xpath,模拟用户登录
    public class Demo2 {
        public static void main(String[] args) throws Exception {
            
            //读取用户在键盘的输入信息
             Scanner scanner = new Scanner(System.in);
            System.out.print("用户名:");
            String username = scanner.nextLine();
            System.out.print("密码:");
            String password = scanner.nextLine();
            
            //解析XML文件,并查询指定的元素
             SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new File("src/cn/itcast/xml/xpath/users.xml"));
            String xpath = "//user[@username='"+username+"' and @password='"+password+"']";
            Element element = (Element) document.selectSingleNode(xpath);
            
            //输出结果
            if(element!=null){
                System.out.println("登录成功");
            }else{
                System.out.println("登录失败");
            }
        }
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <root>
        <user id="u01" username="jack" password="123456"/>
        <user id="u02" username="marry" password="654321"/>
    </root>

    3 简单工厂设计模式
      1)目的就是统一管理访问层的所有Dao,让Service在Dao的处理上相对独立
      2)引用DaoFactory来管理所有的具体Dao,并采用单例模式限制DaoFactory的个数

    package cn.itcast.xml.model;
    
    //单例的Dao工厂
    public class DaoFactory {
        
        //NO1
        private DaoFactory(){}
        
        //NO2
        public static DaoFactory getDaoFactory(){
            if(daoFactory==null){
                daoFactory = new DaoFactory();
            }
            return daoFactory;
        }
        
        //NO3
        private static DaoFactory daoFactory;
        
        public IDao getDao(){
            return new DaoJdbc();
        }
    }
    package cn.itcast.xml.model;
    
    public class DaoHibernate implements IDao {
        public void create() {
            System.out.println("DaoHibernate::create()");
        }
    }
    package cn.itcast.xml.model;
    
    //访问层
    public class DaoJdbc implements IDao{
        public void create(){
            System.out.println("DaoJdbc::create()");
        }
    }
    package cn.itcast.xml.model;
    
    public interface IDao {
        public void create();
    }
    package cn.itcast.xml.model;
    
    //业务层(不变)
    public class Service {
        public void create(){
            DaoFactory daoFactory = DaoFactory.getDaoFactory();
            IDao iDao = daoFactory.getDao();
            iDao.create();
        }
    }
    package cn.itcast.xml.model;
    
    //表现层
    public class Demo1 {
        public static void main(String[] args) {
            Service service = new Service();
            service.create();
        }
    }

    4 分层结构设计思想
      1)将各个不同功能的代码块,分离出来,避免不同功能的代码耦合,为程序扩展和维护提供方便。

    package cn.itcast.xml.example1;
    //(分层结构):模拟用户登录
    import java.io.File;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    public class LoginBusiness {
        //测试
        public static void main(String[] args) throws Exception {
            
            LoginUI loginUI = new LoginUI();
            LoginBusiness lognBusiness = new LoginBusiness();
            
            User user = loginUI.input();
            boolean flag = lognBusiness.check(user);
            
            loginUI.output(flag);
            
        }
        //判段
        public boolean check(User user) throws Exception{
            boolean flag = false;
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new File("src/cn/itcast/xml/xpath/users.xml"));
            String xpath = "//user[@username='"+user.getUsername()+"' and @password='"+user.getPassword()+"']";
            Element element = (Element) document.selectSingleNode(xpath);
            if(element!=null){
                flag = true;
            }
            return flag;
        }
    }
    package cn.itcast.xml.example1;
    
    import java.util.Scanner;
    
    //输入输出
    public class LoginUI {
        public User input(){
            User user = new User();
            Scanner scanner = new Scanner(System.in);
            System.out.print("用户名:");
            String username = scanner.nextLine();
            System.out.print("密码:");
            String password = scanner.nextLine();
            user.setUsername(username);
            user.setPassword(password);
            return user;
        }
        public void output(boolean flag){
            if(flag){
                System.out.println("登录成功");
            }else{
                System.out.println("登录失败");
            }
        }
    }
    package cn.itcast.xml.example1;
    
    public class User {
        private String id;
        private String username;
        private String password;
        public User(){}
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <root>
        <user id="u01" username="jack" password="123456"/>
        <user id="u02" username="marry" password="654321"/>
    </root>


    *5 案例
      1)以分层思想,模拟用户登录
      2)通过配置文件解析/反射/运行某个类的方法

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
        <class>
            <className>cn.itcast.xml.example2.Person</className>
            <methodName>jump</methodName>
            <argType>java.lang.String</argType>
            <argValue>李四</argValue>
        </class>
    </root>
    package cn.itcast.xml.example2;
    
    public class Person {
        public void run(String who){
            System.out.println("Person::run():" + who);
        }
        public void jump(String who){
            System.out.println("Person::jump():" + who);
        }
    }
    package cn.itcast.xml.example2;
    
    import java.io.File;
    import java.lang.reflect.Method;
    import org.dom4j.Document;
    import org.dom4j.io.SAXReader;
    
    //基于XML配置文件,解析,反射,运行程序
    public class Demo1 {
        public static void main(String[] args) throws Exception {
            //解析xml文件
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new File("src/cn/itcast/xml/example2/config.xml"));
            String className = document.selectSingleNode("//className").getText();
            String methodName = document.selectSingleNode("//methodName").getText();
            String argType = document.selectSingleNode("//argType").getText();
            String argValue = document.selectSingleNode("//argValue").getText();
            
            //反射创建对象并执行方法
             Class clazz = Class.forName(className);
            Method method = clazz.getMethod(methodName,Class.forName(argType));
            method.invoke(clazz.newInstance(),argValue);
        }
    }

       3)分层结构的学员信息案例

    dao

    package cn.itcast.xml.example3.dao;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.dom4j.io.OutputFormat;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    import cn.itcast.xml.example3.domain.Student;
    
    public class StudentDao {
        //根据编号更新学员信息
        public void update(Student student) throws Exception {
            Document document = getDocument();
            String xpath = "//student[@id='"+student.getId()+"']";
            Element element = (Element) document.selectSingleNode(xpath);
            if(element!=null){
                element.element("name").setText(student.getName());
                element.element("age").setText(student.getAge());
                write2xml(document);
            }else{
                System.out.println("查无此学员");
            }
    
        }
        //根据编号显示学员信息
        public void read(String id) throws Exception{
            Document document = getDocument();
            String xpath = "//student[@id='"+id+"']";
            Element element = (Element) document.selectSingleNode(xpath);
            if(element!=null){
                System.out.println("编号:" + element.attributeValue("id"));
                System.out.println("姓名:" + element.elementText("name"));
                System.out.println("年龄:" + element.elementText("age"));
            }else{
                System.out.println("查无此学员");
            }
        }
        //根据编号删除某位学员的信息
        public void delete(String id) throws Exception{
            Document document = getDocument();
            String xpath = "//student[@id='"+id+"']";
            Element element = (Element) document.selectSingleNode(xpath);
            if(element!=null){
                element.getParent().remove(element);
                write2xml(document);
            }else{
                System.out.println("查无此学员");
            }
        }
        //增加学员的信息
        public boolean create(Student student) throws Exception{
            boolean flag = false;
            if(student!=null){
                Document document = null;
                try {
                    document = getDocument();
                } catch (Exception e) {
                    //创建空XML文件
                    document = DocumentHelper.createDocument();
                    //创建<students>根元素
                    document.addElement("students");
                }
                Element rootElement = document.getRootElement();
                Element studentElement = rootElement.addElement("student");
                studentElement.addAttribute("id",student.getId());
                studentElement.addElement("name").setText(student.getName());
                studentElement.addElement("age").setText(student.getAge());
                write2xml(document);
                flag = true;
            }
            return flag;
        }
        //将内存中的Document写到硬盘
        private void write2xml(Document document) throws Exception {
            OutputFormat format = OutputFormat.createPrettyPrint();
            OutputStream os = new FileOutputStream("src/cn/itcast/xml/example3/db/students.xml");
            XMLWriter xmlWriter = new XMLWriter(os,format);
            xmlWriter.write(document);
            xmlWriter.close();
        }
        //取得Document对象
        private Document getDocument() throws Exception {
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new File("src/cn/itcast/xml/example3/db/students.xml"));
            return document;
        }
    
    }

    domain

    package cn.itcast.xml.example3.domain;
    
    public class Student {
        private String id;
        private String name;
        private String age;
        public Student(){}
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) throws Exception {
            if(name.matches("[a-zA-Z]+")){
                this.name = name;
            }else{
                throw new Exception();
            }
        }
        public String getAge() {
            return age;
        }
        public void setAge(String age) throws Exception {
            if(age.matches("[0-9]+")){
                this.age = age;
            }else{
                throw new Exception();
            }
        }
    }

    ui

    package cn.itcast.xml.example3.ui;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    
    //id的自增长
    public class IdUtil {
        public static String getId() throws Exception{
            BufferedReader br = new BufferedReader(new FileReader("src/cn/itcast/xml/example3/ui/id.txt"));
            String id = br.readLine();//"2011100801"(字符串)
            int temp = Integer.parseInt(id)+1;//2011100802(int型)
            BufferedWriter bw = new BufferedWriter(new FileWriter("src/cn/itcast/xml/example3/ui/id.txt"));
            bw.write(temp+"");
            bw.flush();
            bw.close();
            return id;
        }
    }
    package cn.itcast.xml.example3.ui;
    
    import java.util.Scanner;
    import cn.itcast.xml.example3.dao.StudentDao;
    import cn.itcast.xml.example3.domain.Student;
    
    public class StudentUI {
        public static void main(String[] args) throws Exception {
            input();
        }
        public static void input() throws Exception{
    
            Scanner scanner = new Scanner(System.in);
            System.out.print("学员的编号:");
            String id = scanner.nextLine();
            System.out.print("更新学员的姓名:");
            String name = scanner.nextLine();
            System.out.print("更新学员的年龄:");
            String age = scanner.nextLine();
            Student student = new Student();
            student.setId(id);
            student.setName(name);
            student.setAge(age);
            StudentDao studentDao = new StudentDao();
            studentDao.update(student);
            
            
            /*键盘输入学员信息
            Scanner scanner = new Scanner(System.in);
            System.out.print("查询学员的编号:");
            String id = scanner.nextLine();
            StudentDao studentDao = new StudentDao();
            studentDao.read(id);
            Scanner scanner = new Scanner(System.in);
            System.out.print("删除学员的编号:");
            String id = scanner.nextLine();
            StudentDao studentDao = new StudentDao();
            studentDao.delete(id);
            Scanner scanner = new Scanner(System.in);
            System.out.print("用户名:" );
            String name = scanner.nextLine();
            System.out.print("年龄:" );
            String age = scanner.nextLine();
            //封装成JavaBean对象
            Student student = new Student();
            student.setId(IdUtil.getId());
            student.setName(name);
            student.setAge(age);
            //调用Dao对象
            StudentDao studentDao = new StudentDao();
            boolean flag = studentDao.create(student);
            if(flag){
                System.out.println("操作成功");
            }else{
                System.out.println("操作失败");
            }
            */
        }
    }

    db

    <?xml version="1.0" encoding="UTF-8"?>
    
    <students> 
      <student id="2011100801"> 
        <name>keke</name>  
        <age>11</age> 
      </student> 
    </students>

    6 SAX解析器
      1)sun公司提供的一个基于事件的xml解析器
      2)SAXParser是SAX解析器的核心类,在使用过程中,需要一个SAX处理器,该处理器必须扩展DefaultHandler
      3)SAX解析器在解析XML文件时,会根据XML文件此时的状态,即开始标签,结束标签,调用SAX处理器对应的方法
      4)SAX解析器在解析XML文件时,自动导航,无需像dom4j一样,人为导航
      5)SAX解析器会将空白字符当作一个有效字符对待

    package cn.itcast.xml.sax;
    
    import java.io.File;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    import org.xml.sax.Attributes;
    import org.xml.sax.helpers.DefaultHandler;
    
    //使用sax解析器解析xml文件
    public class Demo1 {
        public static void main(String[] args) throws Exception {
            //创建SAX解析器工厂
            SAXParserFactory factory = SAXParserFactory.newInstance();
            //创建SAX解析器
            SAXParser saxParser = factory.newSAXParser();
            //加载xml文件
            saxParser.parse(
                    new File("src/cn/itcast/xml/sax/car.xml"),
                    new MyHandler());
        }
    }
    //自定义SAX处理器
    class MyHandler extends DefaultHandler{
        private long begin;
        public void startDocument(){
            System.out.println("解析XML文件开始");
            begin = System.currentTimeMillis();
        } 
        public void endDocument() {
            System.out.println("解析XML文件结束");
            long end = System.currentTimeMillis();
            System.out.println("解析XML共用" + (end-begin) + "毫秒");
        }
        public void startElement(
                String uri, 
                String localName, 
                String qName, 
                Attributes attributes){
            System.out.println("<"+qName+">");
            System.out.println("有"+attributes.getLength()+"个属性");
            System.out.println(attributes.getValue("出产时间"));
        } 
        public void endElement(
                String uri, 
                String localName, 
                String qName){
            System.out.println("</"+qName+">");
        } 
        public void characters(
                char[] ch, 
                int start, 
                int length){
            String content = new String(ch,start,length);
            if(content.trim().length()>0){
                System.out.println(content);
            }
        } 
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <车辆清单>
        <汽车>
            <车牌 出产时间="2011年">奥迪</车牌>
            <产地>北京</产地>
            <单价>30</单价>
        </汽车>
    </车辆清单>

    SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:

        •解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。

        •解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。

        •解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。

    image

    阅读DefaultHandler API文档,常用方法:startElement、endElement、characters

    使用JAXP进行DOM解析

        javax.xml.parsers 包中的DocumentBuilderFactory用于创建DOM模式的解析器对象,DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。

    获得JAXP中的DOM解析器

    • 调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂。
    • 调用工厂对象的 newDocumentBuilder方法得到 DOM 解析器对象。
    • 调用 DOM 解析器对象的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象,从而可以利用DOM特性对整个XML文档进行操作了。
    DOM编程

    lDOM模型(Document Object Model)

    •DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。

    •在DOM中,节点之间关系如下:

        •位于一个节点之上的节点是该节点的父节点(parent)

        •一个节点之下的节点是该节点的子节点(children)

        •同一层次,具有相同父节点的节点是兄弟节点(sibling)

        •一个节点的下一个层次的节点集合是节点后代(descendant)

        •父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)

    •节点类型(下页ppt)

    Node对象

        Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。(查看API文档)

        Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。

    DOM方式解析XML文件(XML文件最好是有效的)

    •遍历所有节点

    •查找某一个节点

    •删除结点

    •更新结点

    •添加节点

    DOM读取XML文件

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder domParser = factory.newDocumentBuilder();
        Document document = domParser.parse(new File("src/cn/itcast/xml/parser/dom/car.xml"));
        Element rootElement = document.getDocumentElement();
        System.out.println(rootElement.getNodeName());
        NodeList nodeList = rootElement.getElementsByTagName("汽车");
        System.out.println("共有"+nodeList.getLength()+"辆汽车");
        System.out.println("--------------------");
        for(int i=0;i<nodeList.getLength();i++){
        Element element = (Element) nodeList.item(i);
        String band = element.getElementsByTagName("车牌").item(0).getTextContent();
        String place = element.getElementsByTagName("产地").item(0).getTextContent();
        String price = element.getElementsByTagName("单价").item(0).getTextContent();
        String time = element.getElementsByTagName("车牌").item(0).getAttributes().getNamedItem("出产时间").getTextContent();
        System.out.println("车牌:" + band);
        System.out.println("产地:" + place);
        System.out.println("单价:" + price);
        System.out.println("出产时间:" + time);
        System.out.println("--------------------");
        }

    DOM更新XML文件

    @Test
    public void testUpdate() throws Exception {
    Document document = getDocument();
    Element element = (Element) document.getElementsByTagName("汽车").item(1);
    element.getElementsByTagName("单价").item(0).setTextContent("30万");
    write2xml(document);
    }
    @Test
    public void testDelete() throws Exception {
    Document document = getDocument();
    Element element = (Element) document.getElementsByTagName("汽车").item(2);
    element.getParentNode().removeChild(element);
    write2xml(document);
    }
    @Test
    public void testCreate() throws Exception {
    Document document = getDocument();
    Element rootElement = document.getDocumentElement();
    Element element = document.createElement("汽车");
    Text text = document.createTextNode("我的汽车");
    element.appendChild(text);
    rootElement.appendChild(element);
    write2xml(document);
    }
    private void write2xml(Document document) throws Exception {
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer();
    transformer.transform(new DOMSource(document),new StreamResult(new File("src/cn/itcast/xml/parser/dom/car.xml")));
    }
    private Document getDocument() throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder domParser = factory.newDocumentBuilder();
    Document document = domParser.parse(new File("src/cn/itcast/xml/parser/dom/car.xml"));
    return document;
    }

    DOM写入XML文档

    javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出,利用这个对象,可以把Document对象又重新写入到一个XML文件中。

    Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:

        •javax.xml.transform.dom.DOMSource类来关联要转换的document对象,

        •用javax.xml.transform.stream.StreamResult 对象来表示数据的目的地。

    Transformer对象通过TransformerFactory获得。

    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer = tf.newTransformer();
    DOMSource source = new DOMSource(document);
    StreamResult result = new StreamResult(new File("src/cn/itcast/xml/car.xml"));
    transformer.transform(source,result);

    DOM类和SAX类的区别

    DOM

        •很方便对文档进行遍历

        •对文档curd也特别方便

        •ml文档比较大的时候,dom解析占用的内存也会比较大,浪费系统资源。所以dom解析这种方式不适合解析大的xml文档。

    SAX

        •解析文件速度快,占用资源(内存)少。

        •sax解析只适合读取文档数据,不适合对文档进行增删改。

  • 相关阅读:
    详解git pull和git fetch的区别
    什么是移臂调度,什么是旋转调度?
    常用的资源分配策略有哪两种?在每一种策略中,资源请求队列的排序原则是什么?
    什么是虚拟资源,对主存储器而言,用户使用的虚拟资源是什么?
    进程调度的任务是什么,线程调度的任务是什么?
    用于进程控制的原语主要由哪几个,每个原语的执行将使进程的状态发生什么变化?
    试说明进程创建的主要功能是什么?
    什么是线程,线程与进程有什么区别?
    什么是进程互斥,什么是进程同步,同步和互斥这两个概念有什么联系和区别?
    n个并发进程共用一个公共变量Q,写出用信号灯实现n个进程互斥的程序描述,给出信号灯值得取值范围,并说明每个取值范围的物理意义。
  • 原文地址:https://www.cnblogs.com/sunhan/p/3542143.html
Copyright © 2020-2023  润新知