读写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.代码案例:略

浙公网安备 33010602011771号