Java中使用DOM和SAX解析XML文件的方法示例
dom4j介绍 dom4j是一个简单的开源库,用于处理XML、 XPath和XSLT,它基于Java平台,使用Java的集合框架,全面集成了DOM,SAX和JAXP。
dom4j的使用 (Properties->Java Build Path -> Add External JARs...)。 之后就可以使用其提供的API进行编程。
程序实例1 package com.example.xml.dom4j; import java.io.FileOutputStream; import java.io.FileWriter; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; /** * dom4j框架学习 使用dom4j框架创建xml文档并输出保存 * */ public class Dom4JTest1 { public static void main(String[] args) throws Exception { // 第一种方式:创建文档,并创建根元素 // 创建文档:使用了一个Helper类 Document document = DocumentHelper.createDocument(); // 创建根节点并添加进文档 Element root = DocumentHelper.createElement("student"); document.setRootElement(root); // 第二种方式:创建文档并设置文档的根元素节点 Element root2 = DocumentHelper.createElement("student"); Document document2 = DocumentHelper.createDocument(root2); // 添加属性 root2.addAttribute("name","zhangsan"); // 添加子节点:add之后就返回这个元素 Element helloElement = root2.addElement("hello"); Element worldElement = root2.addElement("world"); helloElement.setText("hello Text"); worldElement.setText("world text"); // 输出 // 输出到控制台 XMLWriter xmlWriter = new XMLWriter(); xmlWriter.write(document); // 输出到文件 // 格式 OutputFormat format = new OutputFormat(" ",true);// 设置缩进为4个空格,并且另起一行为true XMLWriter xmlWriter2 = new XMLWriter( new FileOutputStream("student.xml"),format); xmlWriter2.write(document2); // 另一种输出方式,记得要调用flush()方法,否则输出的文件中显示空白 XMLWriter xmlWriter3 = new XMLWriter(new FileWriter("student2.xml"),format); xmlWriter3.write(document2); xmlWriter3.flush(); // close()方法也可以 } }
程序Console输出: <?xml version="1.0" encoding="UTF-8"?> <student/> 生成的一个xml文档: <?xml version="1.0" encoding="UTF-8"?> <student name="zhangsan"> <hello>hello Text</hello> <world>world text</world> </student>
程序实例2 首先,待分析的文档如下: <?xml version="1.0" encoding="UTF-8"?> <students name="zhangsan"> <hello name="lisi">hello Text1</hello> <hello name="lisi2">hello Text2</hello> <hello name="lisi3">hello Text3</hello> <world name="wangwu">world text1</world> <world name="wangwu2">world text2</world> <world >world text3</world> </students> package com.example.xml.dom4j; import java.io.File; import java.util.Iterator; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.DOMReader; import org.dom4j.io.SAXReader; /** * dom4j框架学习: 读取并解析xml * * */ public class Dom4JTest2 { public static void main(String[] args) throws Exception { SAXReader saxReader = new SAXReader(); Document document = saxReader.read(new File("students.xml")); // 获取根元素 Element root = document.getRootElement(); System.out.println("Root: " + root.getName()); // 获取所有子元素 List<Element> childList = root.elements(); System.out.println("total child count: " + childList.size()); // 获取特定名称的子元素 List<Element> childList2 = root.elements("hello"); System.out.println("hello child: " + childList2.size()); // 获取名字为指定名称的第一个子元素 Element firstWorldElement = root.element("world"); // 输出其属性 System.out.println("first World Attr: " + firstWorldElement.attribute(0).getName() + "=" + firstWorldElement.attributeValue("name")); System.out.println("迭代输出-----------------------"); // 迭代输出 for (Iterator iter = root.elementIterator(); iter.hasNext();) { Element e = (Element) iter.next(); System.out.println(e.attributeValue("name")); } System.out.println("用DOMReader-----------------------"); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); // 注意要用完整类名 org.w3c.dom.Document document2 = db.parse(new File("students.xml ")); DOMReader domReader = new DOMReader(); // 将JAXP的Document转换为dom4j的Document Document document3 = domReader.read(document2); Element rootElement = document3.getRootElement(); System.out.println("Root: " + rootElement.getName()); } }
代码运行后输出: Root: students total child count: 6 hello child: 3 first World Attr: name=wangwu 迭代输出----------------------- lisi lisi2 lisi3 wangwu wangwu2 null 用DOMReader----------------------- Root: students
SAX解析XML 大概的讲的差不多了 接下来开始讲解解析的步骤 package com.example.demo; import java.io.Serializable; public class Person implements Serializable { /** * */ private static final long serialVersionUID = 1L; private String _id; private String _name; private String _age; public String get_id() { return _id; } public void set_id(String _id) { this._id = _id; } public String get_name() { return _name; } public void set_name(String _name) { this._name = _name; } public String get_age() { return _age; } public void set_age(String _age) { this._age = _age; } } 接下来 我们要实现一个ContentHandler 用来解析XML public class SAX_parserXML extends DefaultHandler { /** * 当开始解析xml文件的声明的时候就会触发这个事件,可以做一些初始化的工作 * */ @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); } /** * 当开始解析元素的开始标签的时候,就会触发这个事件 * */ @Override public void startElement(String uri,Attributes attributes) throws SAXException { // TODO Auto-generated method stub super.startElement(uri,localName,qName,attributes); } /** * 当读到文本元素的时候要触发这个事件. * */ @Override public void characters(char[] ch,int length) throws SAXException { // TODO Auto-generated method stub super.characters(ch,start,length); } /** * 当读到结束标签的时候 就会触发这个事件 * */ @Override public void endElement(String uri,String qName) throws SAXException { // TODO Auto-generated method stub super.endElement(uri,qName); } } 首先 我们创建一个list 用来保存解析出来的person数据 List<Person> persons; 但是?在哪里初始化呢?我们可以在startDocument()里面初始化,因为当开始解析xml文件的声明的时候就会触发这个事件所以放在这里比较合适 /** * 当开始解析xml文件的声明的时候就会触发这个事件,可以做一些初始化的工作 * */ @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); // 初始化list persons = new ArrayList<Person>(); } 接下来 就要开始解析了 /** * 当开始解析元素的开始标签的时候,attributes); // 如果读到是person标签 开始存储 if (localName.equals("person")) { person = new Person(); person.set_id(attributes.getValue("id")); } curNode = localName; } 上面的代码中 localName表示当前解析到的元素名 //步骤 //1.判断是否是person元素 //2.创建新的Person对象 //3.获取id 添加到Person对象中 curNode 用来保存当前的元素名 在characters中会使用到 /** * 当读到文本元素的时候要触发这个事件. * */ @Override public void characters(char[] ch,length); if (person != null) { //取出目前元素对应的值 String txt = new String(ch,length); //判断元素是否是name if (curNode.equals("name")) { //将取出的值添加到person对象 person.set_name(txt); } else if (curNode.equals("age")) { person.set_age(txt); } } } 接下来是介绍标签结束的时候需要做的事情 /** * 当读到结束标签的时候 就会触发这个事件 * */ @Override public void endElement(String uri,String qName) throws SAXException { // TODO Auto-generated method stub super.endElement(uri,qName); // 如果是 并且person不为空,添加到list if (localName.equals("person") && person != null) { persons.add(person); person = null; } curNode = ""; } 解析的事情结束了 大概流程就是 public List<Person> ReadXML(InputStream is) { SAXParserFactory factory = SAXParserFactory.newInstance(); try { SAXParser parser = factory.newSAXParser(); // 第一种方法 // parser.parse(is,this); // 第二种方法 XMLReader reader = parser.getXMLReader(); reader.setContentHandler(this); reader.parse(new InputSource(is)); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return persons; } 上面的代码就不解释了 只要将inputStream对象传入 就可以解析出内容 package com.example.demo.Utils; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import com.example.demo.Person; public class SAX_parserXML extends DefaultHandler { List<Person> persons; Person person; // 当前节点 String curNode; public List<Person> ReadXML(InputStream is) { SAXParserFactory factory = SAXParserFactory.newInstance(); try { SAXParser parser = factory.newSAXParser(); // 第一种方法 // parser.parse(is,this); // 第二种方法 XMLReader reader = parser.getXMLReader(); reader.setContentHandler(this); reader.parse(new InputSource(is)); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return persons; } /** * 当开始解析xml文件的声明的时候就会触发这个事件,可以做一些初始化的工作 * */ @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); // 初始化list persons = new ArrayList<Person>(); } /** * 当开始解析元素的开始标签的时候,attributes); // 如果读到是person标签 开始存储 if (localName.equals("person")) { person = new Person(); person.set_id(attributes.getValue("id")); } curNode = localName; } /** * 当读到文本元素的时候要触发这个事件. * */ @Override public void characters(char[] ch,length); if (person != null) { // 取出目前元素对应的值 String txt = new String(ch,length); // 判断元素是否是name if (curNode.equals("name")) { // 将取出的值添加到person对象 person.set_name(txt); } else if (curNode.equals("age")) { person.set_age(txt); } } } /** * 当读到结束标签的时候 就会触发这个事件 * */ @Override public void endElement(String uri,qName); // 如果是person结尾 并且person不为空,添加到list if (localName.equals("person") && person != null) { persons.add(person); person = null; } curNode = ""; } } 写个方法调用下这个类 List<Person> persons = new SAX_parserXML().ReadXML(is); StringBuffer buffer = new StringBuffer(); for (int i = 0; i < persons.size(); i++) { Person person =persons.get(i); buffer.append("id:" + person.get_id() + " "); buffer.append("name:" + person.get_name() + " "); buffer.append("age:" + person.get_age() + "n"); } Toast.makeText(activity,buffer,Toast.LENGTH_LONG).show(); 如果你看到下面的界面 说明解析成功了~ 小结: DOM(文件对象模型)解析:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以根据DOM接口来操作这个树结构了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |