SAX解析
1DOM解析与SAX解析比较:
DOM解析 |
SAX解析 |
原理: 一次性加载xml文档,不适合大容量的文件读取 |
原理: 加载一点,读取一点,处理一点。适合大容量文件的读取 |
DOM解析可以任意进行增删改成 |
SAX解析只能读取 |
DOM解析任意读取任何位置的数据,甚至往回读 |
SAX解析只能从上往下,按顺序读取,不能往回读 |
DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。 |
SAX解析基于事件的编程方法。java开发编码相对复杂。 |
2 SAX解析工具:
SAX解析工具- Sun公司提供的。内置在jdk中。org.xml.sax.*
核心的API:
SAXParser类: 用于读取和解析xml文件对象
parse(File f, DefaultHandler dh)方法: 解析xml文件
参数一: File:表示 读取的xml文件。
参数二: DefaultHandler: SAX事件处理程序。使用DefaultHandler的子类
例如:{
1.创建SAXParser对象
SAXParser parser=SAXParserFactory.newInstance().newSAXParser();
2.调用parse方法
parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());
}
3.DefaultHandler类的API:
void startDocument() : 在读到文档开始时调用
void endDocument() :在读到文档结束时调用
void startElement(String uri, String localName, String qName, Attributes attributes) :读到开始标 签时调用
void endElement(String uri, String localName, String qName) :读到结束标签时调用
void characters(char[] ch, int start, int length) : 读到文本内容时调用
3.SAM解析练习:
1.基本练习,查看函数调用;
SamExercise.java:
package com.dom4j.SAM; import java.io.File; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; public class SamExercise { public static void main(String[] args) throws Exception, SAXException { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); parser.parse(new File("./src/contact.xml"), new MyDefalutHandler()); } }
MyDefalutHandler.java:
package com.dom4j.SAM; import javax.xml.stream.events.StartDocument; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class MyDefalutHandler extends DefaultHandler{ @Override public void startDocument() throws SAXException { System.out.println("MyDefalutHandler.startDocument()"); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("MyDefalutHandler.startElement()->>>" + qName); } @Override public void characters(char[] ch, int start, int length) throws SAXException { System.out.println("MyDefalutHandler.characters()->>>" + new String(ch, start, length)); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("MyDefalutHandler.endElement()->>>" + qName); } @Override public void endDocument() throws SAXException { System.out.println("MyDefalutHandler.endDocument()"); } }
2.读取打印出来xml文件:
contact.xml:
<?xml version="1.0" encoding="gb2312"?> <contactList> <contact id="001"> <name>张三</name> <age>20</age> <phone>134222223333</phone> <email>zhangsan@qq.com</email> <qq>432221111</qq> </contact> <contact id="003" value="hello"> <name>lisi</name> <age>20</age> <phone>134222225555</phone> <email>lisi@qq.com</email> <qq>432222222</qq> </contact> <contact></contact> </contactList>
DisplayAllContent.java:
package com.dom4j.SAM; import java.io.File; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; public class DisplayAllContent { public static void main(String[] args) throws Exception, SAXException { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); MyDisplayAllContentHandle handle = new MyDisplayAllContentHandle(); parser.parse(new File("./src/contact.xml"), handle); System.out.println(handle.getContent()); } }
MyDisplayAllContentHandle:
package com.dom4j.SAM; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class MyDisplayAllContentHandle extends DefaultHandler { private static StringBuffer sb; static{ sb = new StringBuffer(); } public String getContent(){ return sb.toString(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { sb.append("<"); sb.append(qName); for(int i = 0; i < attributes.getLength(); i++){ sb.append(" " + attributes.getQName(i)); sb.append("=" + "\"" + attributes.getValue(i) + "\""); } sb.append(">"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { sb.append(new String(ch, start, length)); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { sb.append("</"); sb.append(qName + ">"); } }
3.将xml文件内容放在一个类中,并输出:
contact.java:
package com.dom4j.SAM; public class contact { private String id; private String name; private String age; private String qq; private String email; private String phone; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getqq() { return qq; } public void setqq(String qq) { this.qq = qq; } public String getemail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @Override public String toString() { return "Person \n id=" + id + ", name=" + name + ", age=" + age + ", qq=" + qq + ", email=" + email + ", phone=" + phone + "\n"; } }
ReadValue.java:
package com.dom4j.SAM; import java.io.File; import java.util.ArrayList; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; public class ReadValue{ public static void main(String[] args) throws Exception, SAXException { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); MyReadValueHandle handle = new MyReadValueHandle(); parser.parse(new File("./src/contact.xml"), handle); ArrayList<contact> list = handle.getList(); for(contact acontact : list){ System.out.println(acontact); } } }
MyReadValueHandle.java:
package com.dom4j.SAM; import java.util.ArrayList; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class MyReadValueHandle extends DefaultHandler { private ArrayList<contact> list = new ArrayList<contact>(); private contact acontact; private String curTag; public ArrayList<contact> getList(){ return list; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { curTag = qName; if(qName.equals("contact")){ acontact = new contact(); acontact.setId(attributes.getValue("id")); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { String content = new String(ch, start, length); if("name".equals(curTag)){ acontact.setName(content); } if("age".equals(curTag)){ acontact.setAge(content); } if("phone".equals(curTag)){ acontact.setPhone(content); } if("email".equals(curTag)){ acontact.setEmail(content); } if("qq".equals(curTag)){ acontact.setqq(content); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { curTag = null;//注意!!避免换行空格的影响 if(qName.equals("contact")){ list.add(acontact); } } }
4.设计一个通讯录程序
联系人: 编号 姓名 性别 年龄 电话 QQ 邮箱
功能要求:
添加联系人
修改联系人
删除联系人
查询所有联系人
思路:添加联系人的时候先把输入的内容放在一个配置文件中config.txt,然后用BeanUtil框架从这个配置文件中读取内容用dom解析,放到contact.xml中,修改的时候直接用xpath技术得到id,通过dom解析修改xml中的内容,删除和修改类同,查询的时候直接用的SAX解析;
代码:
main.java
package com.dom4j.contacts; import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { Scanner cin = new Scanner(System.in); String operate; while(true){ System.out.println("================"); System.out.println("【1】添加联系人"); System.out.println("【2】修改联系人"); System.out.println("【3】删除联系人"); System.out.println("【4】查询所有联系人"); System.out.println("【Q】退出程序"); System.out.println("=================="); operate = cin.nextLine(); if(operate.equals("Q")){ break; } if(operate.equals("1")){ new AlterContact().addContact(); } if(operate.equals("2")){ new AlterContact().alterContact(); } if(operate.equals("3")){ new AlterContact().deleteContact(); } if(operate.equals("4")){ new QueryContact().display(); } } } }
contact.java:
package com.dom4j.contacts; public class Contact { private String id, name, sex, phone, qq, email; private String age; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public String toString() { return id + "\t" + name + "\t" + age + "\t" + sex + "\t" + phone + "\t" + qq + "\t" + email; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getQq() { return qq; } public void setQq(String qq) { this.qq = qq; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
AlterContact.java:
package com.dom4j.contacts; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.List; import java.util.Properties; import java.util.Scanner; import org.apache.commons.beanutils.BeanUtils; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.ElementHandler; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.xml.sax.DocumentHandler; import sun.font.CreatedFontTracker; public class AlterContact { private Scanner cin = new Scanner(System.in); private static Contact contact; private Properties properties; static{ contact = new Contact(); } public void addContact() throws Exception { WriteFile(); //读取配置文件 properties = new Properties(); Class clazz = AlterContact.class; InputStream inputStream = clazz.getResourceAsStream("/config.txt"); //注意这个文件在bin目录下的,并不在src下,错了半天才发现!!! try { properties.load(inputStream); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //向配置文件中读取数据加入xml文件中 Document doc = new SAXReader().read("./src/contact.xml"); List nodes = doc.selectNodes("//contactList"); Element list = (Element)nodes.get(0); Element newContact = list.addElement("contact"); newContact.addAttribute("id", properties.getProperty("id")); newContact.addElement("age").setText(properties.getProperty("age")); newContact.addElement("name").setText(properties.getProperty("name")); newContact.addElement("sex").setText(properties.getProperty("sex")); newContact.addElement("phone").setText(properties.getProperty("phone")); newContact.addElement("qq").setText(properties.getProperty("qq")); newContact.addElement("email").setText(properties.getProperty("email")); //写入xml文件 OutputFormat format = OutputFormat.createPrettyPrint(); FileOutputStream outputStream = new FileOutputStream(new File("./src/contact.xml")); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(outputStream, format); writer.write(doc); writer.close(); System.out.println("添加成功!"); } public void alterContact() throws Exception { System.out.println("请输入您要修改的联系人的编号:"); String id = cin.nextLine(); Document doc = new SAXReader().read(new File("./src/contact.xml")); List list = doc.selectNodes("//contact[@id=" + id + "]"); if(list.size() == 0){ System.out.println("您要修改 的id不存在!"); return; } Element acontact = (Element) list.get(0); System.out.println("您要修改的联系人信息为:"); System.out.println("name: " + acontact.element("name").getText()); System.out.println("sex: " + acontact.element("sex").getText()); System.out.println("age: " + acontact.element("age").getText()); System.out.println("phone: " + acontact.element("phone").getText()); System.out.println("qq: " + acontact.element("qq").getText()); System.out.println("email: " + acontact.element("email").getText()); while(true){ System.out.println("欢迎来到修改系统\t如需退出请按Q键"); System.out.println("请输入您要修改的项目:"); String op = cin.nextLine(); if(op.equals("Q")){ return; } System.out.println("请输入修改的内容:"); String va = cin.nextLine(); acontact.element(op).setText(va); //写入xml文件 OutputFormat format = OutputFormat.createPrettyPrint(); FileOutputStream outputStream = new FileOutputStream(new File("./src/contact.xml")); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(outputStream, format); writer.write(doc); writer.close(); System.out.println("修改成功!"); } } public void deleteContact() throws Exception { System.out.println("请输入您要删除的联系人编号:"); String id = cin.nextLine(); Document doc = new SAXReader().read(new File("./src/contact.xml")); List<Element> list = (List<Element>)doc.selectNodes("//contact[@id=" + id + "]"); if(list.size() == 0){ System.out.println("您要删除的联系人不存在!"); return; } for(Element contact : list){ contact.detach(); } //写入xml文件 OutputFormat format = new OutputFormat().createPrettyPrint(); FileOutputStream out = new FileOutputStream(new File("./src/contact.xml")); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out, format); writer.write(doc); writer.close(); System.out.println("删除成功! "); } private void WriteFile() throws Exception{ BufferedWriter writer = new BufferedWriter(new FileWriter("./bin/config.txt")); //向配置文件中写数据放入对象中 System.out.println("请输入编号:"); String str = cin.nextLine(); writer.write("id=" + str); BeanUtils.setProperty(contact, "id", str); writer.newLine(); System.out.println("请输入姓名:"); str = cin.nextLine(); BeanUtils.setProperty(contact, "name", str); writer.write("name=" + str); writer.newLine(); System.out.println("请输入性别:"); str = cin.nextLine(); BeanUtils.setProperty(contact, "sex", str); writer.write("sex=" + str); writer.newLine(); System.out.println("请输入年龄:"); str = cin.nextLine(); BeanUtils.setProperty(contact, "age", str); writer.write("age=" + str); writer.newLine(); System.out.println("请输入电话号码:"); str = cin.nextLine(); BeanUtils.setProperty(contact, "phone", str); writer.write("phone=" + str); writer.newLine(); System.out.println("请输入qq:"); str = cin.nextLine(); BeanUtils.setProperty(contact, "qq", str); writer.write("qq=" + str); writer.newLine(); System.out.println("请输入email:"); str = cin.nextLine(); BeanUtils.setProperty(contact, "email", str); writer.write("email=" + str); writer.newLine(); writer.close(); } }
queryContact.java:
package com.dom4j.contacts; import java.io.File; import java.util.ArrayList; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.dom4j.io.SAXReader; import org.xml.sax.SAXException; import com.dom4j.SAM.MyDefalutHandler; public class QueryContact { private ArrayList<Contact>list; public void display() throws Exception, SAXException{ SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); MyQueryHandler dh = new MyQueryHandler(); parser.parse(new File("./src/contact.xml"), dh); list = dh.getList(); System.out.println("id\tname\tage\tsex\tphone\t\tqq\t\temail\t\t"); for(int i = 0; i < list.size(); i++){ System.out.println(list.get(i)); } } }
MyQueryContact.java:
package com.dom4j.contacts; import java.util.ArrayList; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import com.sun.org.apache.xalan.internal.xsltc.compiler.Parser; public class MyQueryHandler extends DefaultHandler { private ArrayList<Contact>list = new ArrayList<Contact>(); private String tag; private Contact contact; public ArrayList<Contact> getList(){ return list; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { tag = qName; if("contact".equals(qName)){ contact = new Contact(); contact.setId(attributes.getValue("id")); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { String content = new String(ch, start, length); if("id".equals(tag)){ contact.setId(content); } if("name".equals(tag)){ contact.setName(content); } if("age".equals(tag)){ contact.setAge(content); } if("sex".equals(tag)){ contact.setSex(content); } if("qq".equals(tag)){ contact.setQq(content); } if("phone".equals(tag)){ contact.setPhone(content); } if("email".equals(tag)){ contact.setEmail(content); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { tag = null; if("contact".equals(qName)){ list.add(contact); } } }