*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文件内容作为方法的参数传递给事件处理器。
阅读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解析只适合读取文档数据,不适合对文档进行增删改。