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()+"\t");

                System.out.print("产地:"+car.getPlace()+"\t");

                System.out.print("单价:"+car.getPrice()+"\t");

                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解析只适合读取文档数据,不适合对文档进行增删改。

你可能感兴趣的:(dom4j)