读写XML

一. dom 方式:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。

  1.优点:整个文档树在内存中,允许应用程序对数据和结构做出更改,访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据;

  2.缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;

  3.使用场合:一旦解析了文档还需多次访问这些数据,对XML有修改等复杂操作;

  4.代码案例

    ①.读取XML

      步骤1:设置XML文件

DOMRead.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <head>人</head>
    <students>
        <stu name="张三" id="1">衢州人</stu>
        <stu name="李四" id="2">杭州人</stu>
    </students>
    <teachers>
        <tea>
            <name>王五</name>
            <address>九华</address>
        </tea>
        <tea>
            <name>王五</name>
            <address>航埠</address>
        </tea>
    </teachers>
</root>

 

      步骤2:设置接收对象

package com.zhengx.dom.model;

import java.util.List;

/**
 * 读取的XML对象
 * 
 * @author Administrator
 *
 */
public class XMLModel {

    // attribute
    private String head;
    private List<StudentModel> stuList;
    private List<TeacherModel> teaList;

    // construction
    public XMLModel(String head, List<StudentModel> stuList,
            List<TeacherModel> teaList) {
        this.head = head;
        this.stuList = stuList;
        this.teaList = teaList;
    }

    public XMLModel() {

    }

    // method
    public String getHead() {
        return head;
    }

    public void setHead(String head) {
        this.head = head;
    }

    public List<StudentModel> getStuList() {
        return stuList;
    }

    public void setStuList(List<StudentModel> stuList) {
        this.stuList = stuList;
    }

    public List<TeacherModel> getTeaList() {
        return teaList;
    }

    public void setTeaList(List<TeacherModel> teaList) {
        this.teaList = teaList;
    }
}
package com.zhengx.dom.model;

/**
 * 学生
 * 
 * @author Administrator
 *
 */
public class StudentModel {

    // attribute
    private String name;
    private String id;
    private String address;

    // construction
    public StudentModel(String name, String id, String address) {
        this.name = name;
        this.id = id;
        this.address = address;
    }

    public StudentModel() {

    }

    // method
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
package com.zhengx.dom.model;

/**
 * 老师
 * 
 * @author Administrator
 *
 */
public class TeacherModel {

    // attribute
    private String name;
    private String address;

    // construction
    public TeacherModel() {

    }

    public TeacherModel(String name, String address) {
        this.name = name;
        this.address = address;
    }

    // method
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}  

      步骤3:读取XML数据到对象,path:XMLRead.xml 存储路径

/**
     * 用dom读取XML中数据
     * @param path XML存储路径
     * @return XML对象
     */
    public static XMLModel readXML(String path) {
        XMLModel xmlModel = new XMLModel();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        Document doc;
        try {
            builder = factory.newDocumentBuilder();
            doc = builder.parse(path);
            System.out.println("XML编码:" + doc.getXmlEncoding());
            System.out.println("XML版本:" + doc.getXmlVersion());
            Element root = doc.getDocumentElement();
            
            // 1.head
            Element head = (Element) root.getElementsByTagName("head").item(0);
            xmlModel.setHead(head.getTextContent());
                
            // 2.students
            Element students = (Element) root.getElementsByTagName("students").item(0);
            NodeList stuNodes = students.getElementsByTagName("stu");
            List<StudentModel> stuList = new ArrayList<StudentModel>();
            StudentModel stuModel;
            Element stuEle;
            for(int i = 0 ; i < stuNodes.getLength() ; i++){
                stuModel = new StudentModel();
                stuEle = (Element) stuNodes.item(i);
                stuModel.setId(stuEle.getAttribute("id"));
                stuModel.setName(stuEle.getAttribute("name"));
                stuModel.setAddress(stuEle.getTextContent());
                stuList.add(stuModel);
            }
            xmlModel.setStuList(stuList);
            
            // 3.teachers
            Element teachers = (Element) root.getElementsByTagName("teachers").item(0);
            NodeList teaNodes = teachers.getElementsByTagName("tea");
            List<TeacherModel> teaList = new ArrayList<TeacherModel>();
            TeacherModel teaModel;
            Element teaEle;
            for(int i = 0 ; i < teaNodes.getLength() ; i++){
                teaModel = new TeacherModel();
                teaEle = (Element) teaNodes.item(i);
                teaModel.setName(teaEle.getElementsByTagName("name").item(0).getTextContent());
                teaModel.setAddress(teaEle.getElementsByTagName("address").item(0).getTextContent());
                teaList.add(teaModel);
            }
            xmlModel.setTeaList(teaList);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return xmlModel;
    }

 

    

    ②.写入XML

      步骤1:设置写入数据

// 1.构造 XML 对象
        List<StudentModel> stuList = new ArrayList<StudentModel>();
        List<TeacherModel> teaList = new ArrayList<TeacherModel>();
        StudentModel stu1 = new StudentModel("敌法师", "1", "近卫");
        StudentModel stu2 = new StudentModel("恐怖利刃", "2", "天灾");
        stuList.add(stu1);
        stuList.add(stu2);
        TeacherModel tea1 = new TeacherModel("先知", "近卫");
        TeacherModel tea2 = new TeacherModel("宙斯", "近卫");
        teaList.add(tea1);
        teaList.add(tea2);
        XMLModel xmlModel = new XMLModel("dota", stuList, teaList);

 

      步骤2:写入XML

/**
     * 用dom向XML中写入数据
     * @param xmlModel 将写入的XML对象
     * @param path XML存储路径
     */
    public static void writeXML(XMLModel xmlModel, String path) {
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        Document doc;
        try {
            builder = dbFactory.newDocumentBuilder();
            doc = builder.newDocument();
            
            //封装节点,并构建XML树
            Element root = doc.createElement("root");
            doc.appendChild(root);
            
            //head
            Element head = doc.createElement("head");
            head.setTextContent(xmlModel.getHead());
            root.appendChild(head);
            
            //students
            Element students = doc.createElement("students");
            root.appendChild(students);
            if(null != xmlModel.getStuList()){
                Element stu;
                for(StudentModel stuModel:xmlModel.getStuList()){
                    stu = doc.createElement("stu");
                    stu.setTextContent(stuModel.getAddress());
                    stu.setAttribute("name", stuModel.getName());
                    stu.setAttribute("id", stuModel.getId());
                    students.appendChild(stu);
                }
            }
            
            //teachers
            Element teachers = doc.createElement("teachers");
            root.appendChild(teachers);
            if(null != xmlModel.getTeaList()){
                Element tea, name , address;
                for(TeacherModel teaModel:xmlModel.getTeaList()){
                    tea = doc.createElement("tea");
                    name = doc.createElement("name");
                    name.setTextContent(teaModel.getName());
                    address = doc.createElement("address");
                    address.setTextContent(teaModel.getAddress());
                    tea.appendChild(name);
                    tea.appendChild(address);
                    teachers.appendChild(tea);
                }
            }
            
            // 转码,写入XML
            TransformerFactory tsFactory = TransformerFactory.newInstance();
            Transformer tf = tsFactory.newTransformer();
            tf.setOutputProperty(OutputKeys.ENCODING, "utf-8");
            DOMSource domSource = new DOMSource(doc);
            StreamResult streamResult = new StreamResult(new File(path));
            tf.transform(domSource, streamResult);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }

     步骤3:XML文件

DOMWrite.xml

<?xml version="1.0" encoding="utf-8" standalone="no"?><root><head>dota</head><students><stu id="1" name="敌法师">近卫</stu><stu id="2" name="恐怖利刃">天灾</stu></students><teachers><tea><name>先知</name><address>近卫</address></tea><tea><name>宙斯</name><address>近卫</address></tea></teachers></root>

 

 

二. sax 方式:事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。(常用)

  1.优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。

  2.缺点:

    ①.不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;

    ②.只需XML文档的少量内容,很少回头访问;机器内存少;

    ③.需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),文档越复杂程序就越复杂;

    ④.单向导航,无法定位文档层次,很难同时访问同一文档的不同部分数据,不支持XPath;

  3.使用场合:Applet;

  4.代码案例

    ①.读取XML

      步骤1:设置XML文件,同 dom 方式

      步骤2:设置接收对象,同 dom 方式

      步骤3:读取XML

    /**
     * 用 SAXBuilder 读取 XML 中数据
     * @param path XML 存储路径
     * @return XML 对象
     */
    public static XMLModel readXML(String path) {
        XMLModel readXMLModel = new XMLModel();
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(path);
            SAXBuilder saxb = new SAXBuilder();
            Document doc = saxb.build(fis);

            // 1.head
            Element root = doc.getRootElement();
            readXMLModel.setHead(root.getChildText("head"));

            // 2.students
            List<StudentModel> stuMList = new ArrayList<StudentModel>();
            StudentModel studentModel = null;
            Element students = root.getChild("students");
            @SuppressWarnings("unchecked")
            List<Element> stuList = students.getChildren();
            for (Element student : stuList) {
                studentModel = new StudentModel();
                studentModel.setAddress(student.getText());
                studentModel.setName(student.getAttributeValue("name"));
                studentModel.setId(student.getAttributeValue("id"));
                stuMList.add(studentModel);
            }
            readXMLModel.setStuList(stuMList);

            // 3.teachers
            List<TeacherModel> teaMList = new ArrayList<TeacherModel>();
            TeacherModel teacherModel = null;
            Element teachers = root.getChild("teachers");
            @SuppressWarnings("unchecked")
            List<Element> teaList = teachers.getChildren();
            for (Element teacher : teaList) {
                teacherModel = new TeacherModel();
                teacherModel.setName(teacher.getChildText("name"));
                teacherModel.setAddress(teacher.getChildText("address"));
                teaMList.add(teacherModel);
            }
            readXMLModel.setTeaList(teaMList);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(null != fis){
                    fis.close();
                    fis = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return readXMLModel;
    }

     

    ②.写入XML

      步骤1:设置写入数据,同 dom 方式

      步骤2:写入XML

/**
     * 用 SAXBuilder 向 XML 中写入数据
     * @param xmlModel 将写入的XML对象
     * @param path 写入的XML存储路径
     */
    public static void writeXML(XMLModel xmlModel, String path) {
        Document doc = new Document();
        Element root = new Element("root");
        doc.addContent(root);

        // head
        Element head = new Element("head");
        head.setText(xmlModel.getHead());
        root.addContent(head);

        // student
        Element students = new Element("students");
        root.addContent(students);
        List<StudentModel> stuList = xmlModel.getStuList();
        Element stu;
        if (null != stuList) {
            for (int i = 0; i < stuList.size(); i++) {
                stu = new Element("stu");
                stu.setAttribute("name", stuList.get(i).getName());
                stu.setText(stuList.get(i).getId());
                students.addContent(stu);
            }
        }

        // teacher
        Element teachers = new Element("teachers");
        root.addContent(teachers);
        List<TeacherModel> teaList = xmlModel.getTeaList();
        Element tea;
        Element name;
        Element address;
        if (null != teaList) {
            for (int i = 0; i < teaList.size(); i++) {
                tea = new Element("tea");
                name = new Element("name");
                address = new Element("address");
                name.setText(teaList.get(i).getName());
                address.setText(teaList.get(i).getAddress());
                tea.addContent(name);
                tea.addContent(address);
                teachers.addContent(tea);
            }
        }

        // 转码,写入XML
        Format format = Format.getCompactFormat();
        format.setEncoding("UTF-8");
        XMLOutputter xmlo = new XMLOutputter(format);
        try {
            xmlo.output(doc, new FileOutputStream(path));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

      步骤3:写入的XML,同 dom 方式

三. dom4j 方式(最优)

  1.优点:具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。支持XPath;

  2.缺点:大量使用了接口,API较为复杂;

  3.代码案例:

    ①.读取XML 

      步骤1:设置XML文件,同 dom 方式

      步骤2:设置接收对象,同 dom 方式

      步骤3:读取XML

/**
     * 用dom4j读取XML中数据
     * @param path XML存储路径
     * @return XML对象
     */
    public static XMLModel readXML(String path) {
        XMLModel xmlModel = new XMLModel();
        SAXReader reader = new SAXReader();
        Document doc;
        try {
            doc = (Document) reader.read(path);
            System.out.println("XML编码:" + doc.getXMLEncoding());
            Element root = doc.getRootElement();
            
            // 1.head
            xmlModel.setHead(root.elementText("head"));
            
            // 2.students
            
            Element students = root.element("students");
            
            @SuppressWarnings("unchecked")
            List<Element> stuEleList = students.elements("stu");
            List<StudentModel> stuList = new ArrayList<StudentModel>();
            StudentModel stuModel;
            for(Element stuEle : stuEleList){
                stuModel = new StudentModel();
                stuModel.setName(stuEle.attributeValue("name"));
                stuModel.setId(stuEle.attributeValue("id"));
                stuModel.setAddress(stuEle.getText());
                stuList.add(stuModel);
            }
            xmlModel.setStuList(stuList);
            
            // 3.teachers
            Element teachers = root.element("teachers");
            @SuppressWarnings("unchecked")
            List<Element> teaEleList = teachers.elements("tea");
            List<TeacherModel> teaList = new ArrayList<TeacherModel>();
            TeacherModel teaModel;
            Element nameEle, addressEle;
            for(Element teaEle : teaEleList){
                teaModel = new TeacherModel();
                nameEle = teaEle.element("name");
                teaModel.setName(nameEle.getText());
                addressEle = teaEle.element("address");
                teaModel.setAddress(addressEle.getText());
                teaList.add(teaModel);
            }
            xmlModel.setTeaList(teaList);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return xmlModel;

    ②.写入XML

      步骤1:设置写入数据,同 dom 方式

      步骤2:写入XML

/**
     * 用dom4j向XML中写入数据
     * @param xmlModel 将写入的XML对象
     * @param path 写入的XML存储路径
     */
    public static void writeXML(XMLModel xmlModel, String path) {
        Document doc = DocumentHelper.createDocument();
        
        //封装节点,并构建XML树
        Element root = doc.addElement("root");
        
        //head
        Element head = root.addElement("head");
        head.setText(xmlModel.getHead());
        
        //students
        Element students = root.addElement("students");
        if(null != xmlModel.getStuList()){
            Element stu;
            for(StudentModel stuModel:xmlModel.getStuList()){
                stu = students.addElement("stu");
                stu.setText(stuModel.getAddress());
                stu.addAttribute("name", stuModel.getName());
                stu.addAttribute("id", stuModel.getId());
            }
        }
        
        //teachers
        Element teachers = root.addElement("teachers");
        if(null != xmlModel.getTeaList()){
            Element tea, name , address;
            for(TeacherModel teaModel:xmlModel.getTeaList()){
                tea = teachers.addElement("tea");
                name = tea.addElement("name");
                name.setText(teaModel.getName());
                address = tea.addElement("address");
                address.setText(teaModel.getAddress());
            }
        }
        
        OutputFormat format = OutputFormat.createPrettyPrint();  
        format.setEncoding("utf-8");
        XMLWriter writer = null;
        try {
            writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(path),"utf-8"),format);  
            writer.write(doc);  
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(null != writer){
                    writer.close();
                    writer = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

 

四. jdom 方式(最差)

  1.优点:极大减少了代码量;

  2.缺点:没有较好的灵活性,性能较差;

  3.使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档;

  4.代码案例:略

 

posted @ 2016-02-19 16:14  郑小肖  阅读(129)  评论(0)    收藏  举报