陌路lui  

前言:xml解析主要分为dom解析和sax解析,dom是W3C组织推荐的处理XML文档的一种方式,sax不是官方标准,但它是xml社区事实上的标准(相当于是一个民间标准),几乎

所有的xml解析器都支持它。dom和sax都是一种模型,都需要使用具体的代码去实现它。dom4j组织根据自己的解析器推出了解析xml的api dom4j,它是一个十分优秀的API,具有

性能优异、功能强大和极易使用的特点,一经推出就风靡。

一、sax解析

1.1sax解析的特点

sax解析xml文件时,遇到开始标签、结束标签、开始解析文件,文件解析结束,字符内容和空白字符时都会触发各自的方法。

优点:适合解析大文件,对内存要求不高。轻量级的解析数据方式,效率更高

缺点:不能随机解析文件,不能修改xml文件,只能进行查询

在基于sax的程序中,有五个最常用的sax事件

startDocument() ---> 解析器发现了文档的开始标签
endDocument()   ---> 解析器发现了文档结束标签
startElement()  ---> 解析器发现了一个起始标签
character()     ---> 解析器发现了标签里面的文本值
endElement()    ---> 解析器发现了一个结束标签

利用SAX解析xml文档,涉及两个部分:解析器和时间处理器。例如:

 

package XMLjiexi;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.sun.org.apache.xerces.internal.xni.QName;

/*
 使用sax解析去解析xml文件,sax解析的机制为遇到开始标签结束标签开始解析文件,遇到文本内容和空白内容都会触发方法,
 特点:适合解析大文件,对内存要求不高,轻量级的解析,效率更高
 缺点:不能随机修改,只能进行查询,不能随机进行解析,因为是从上到下的解析方式
  */
public class Saxparse {
	private List<student> stus;
	private student stu;
	public List<student> read(String filePath) {
		stus=new ArrayList<>();
		
		try {
			//第一步,获取sax解析工厂对象
			SAXParserFactory factory = SAXParserFactory.newInstance();
			//第二步,获得sax解析器对象
			SAXParser parser = factory.newSAXParser();
			//第三步,利用解析器对象解析xml文件,传的第一个is对象为需要解析的xml文件的路径,第二个对象dh为
			//sax解析的关键内容,这个内部类写了很多个方法,解析xml文档的方法,我们只需要去实现五个关键的方法。
			parser.parse(filePath,new DefaultHandler() {
				String cuurentQname;
				@Override
				public void characters(char[] ch, int start, int length) throws SAXException {
					//System.out.println("获取元素内容");
					String text=new String(ch, start, length);
					if("name".equals(this.cuurentQname)) {
						stu.setName(text);
					}else if("age".equals(this.cuurentQname)) {
						stu.setAge(Integer.parseInt(text));
					}
				}

				@Override
				public void endDocument() throws SAXException {
					System.out.println("文档解析结束");
				}
				//当解析到下一个stu时,这个时候已经解析完一个部分了,把这个所有内容保存进list对象stus里面去。
				@Override
				public void endElement(String uri, String localName, String qName) throws SAXException {
						//System.out.println("元素解析结束");
					if(qName.equals("stu")) {
						stus.add(stu);
					}
					this.cuurentQname=null;
				}

				@Override
				public void startDocument() throws SAXException {
					System.out.println("文档开始解析");
				}
				/*各个参数的含义
				 * uri:命名空间
				 * localName:不带前缀名
				 * qName:带前缀名
				 * attributes:属性对象
				 */
				public void startElement(String uri, String localName, String qName, Attributes attributes)
						throws SAXException {
						this.cuurentQname=qName;
					//System.out.println("元素开始解析");
					if(qName.equals("stu")) {
						//当解析到stu时,需要创建一个对象去存储接下来会获取到的属性值
						stu=new student();
						//属性内容可以通过属性名或者索引来获取属性内容
						String id = attributes.getValue("id");
						//属性内容的格式是string类型的,需要把它转换为long内容再存进域对象stu里面。ps:开始设置
						//stu时的属性为long类型
						stu.setId(Long.parseLong(id));
					}
				}
				
			} );
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return stus;
	}
	public static void main(String[] args) {
		List<student> stus = new Saxparse().read("src/XMLjiexi/Student.xml");
		System.out.println(stus.toString());
	}

}

 

二、DOM解析

2.1dom解析的特点

采用dom解析,会将xml文档全部加载到内存当中,然后将xml文档中的所有内容转化为tree上的节点(对象).

优点:可以随机解析,可以修改文件,可以创建xml文件

缺点:适合解析小型文件,对内存要求较高。

三、dom4j解析

3.1dom4j解析简介

dom4j是一个简单、灵活的开放源代码的库。现在很多软件采用的dom4j,使用dom4j开发,需要下载相应的jar包。

3.2dom4j创建、解析、修改xml文件

创建一个和遍历一个xml文档

package XMLjiexi;

import java.io.File;
import java.io.FileOutputStream;
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;
/*
 * 使用dom4japi可以创建和解析和修改xml文件,以下是一些创建和修改相关的操作以及注释
 */
public class Dom4jTest {
	//创建一个新的xml文件
	public void createDom(String file){
		//获得文档对象
		Document document = DocumentHelper.createDocument();
		
		//添加根元素
		Element root = document.addElement("root");
		//根元素下面添加子元素及其属性
		Element city = root.addElement("city");
		city.addAttribute("name", "上海");
		//city元素下面添加子元素及其文本值
		Element num = city.addElement("peopleNumber");
		num.addText("23343");
		Element sal = city.addElement("salary");
		sal.addText("12000");
		Element city1 = root.addElement("city");
		city1.addAttribute("name", "北京");
		//city元素下面添加子元素及其文本值
		Element num1 = city1.addElement("peopleNumber");
		num1.addText("11111");
		Element sal1 = city1.addElement("salary");
		sal1.addText("14000");
		try {
//			输出格式化xml
			OutputFormat format = OutputFormat.createPrettyPrint();
			XMLWriter xw = new XMLWriter(new FileOutputStream(new File(file)),format);
			xw.write(document);
			xw.flush();
			xw.close();
		
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	
	public void readXML(String filePath){
		
		try {
			//获得一个SAXReader对象
			SAXReader reader = new SAXReader();
			File file = new File(filePath);
			//读取这个要解析的xml文件
			Document document = reader.read(file);
			//获得document中的根节点
			Element rootElement = document.getRootElement();
			//获得根节点下面所有的子节点
			List<Element> elements = rootElement.elements();
			//遍历elements集合,拿到每一个子节点
			for(Element e:elements){
				//获得元素的名字和文本值
				String s = e.attributeValue("id");
				System.out.println(e.getName()+"节点的id属性的值为:"+s);
				
				//获得当前这个子节点下面所有的子节点
				List<Element> elements2 = e.elements();
				//遍历elements2集合,拿到每一个子节点
				for(Element e2:elements2){
					System.out.println(e2.getName()+" : "+e2.getText());
				}
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	public static void main(String[] args) {
		Dom4jTest t = new Dom4jTest();
		String filePath = "src/XMLjiexi/app.xml";
		t.createDom(filePath);
	//    t.readXML(filePath);
	}



}

  修改一个xml文件,需要下载相应的jar包

package XMLjiexi;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class Dom4jUpdate {
	public void modifyXML(File filePath) {
		try {
			SAXReader reader = new SAXReader();
			Document document = reader.read(filePath);
			//System.out.println("nihao");
			//定位节点需要用到一个jar包:jaxen-1.1-beta-6.jar
			List list = document.selectNodes("//city/@name");
			//System.out.println("nihaomingtian");
			Iterator iter = list.iterator();
			while(iter.hasNext()) {
				Attribute att = (Attribute)iter.next();
				if(att.getValue().equals("上海")) {
					att.setValue("成都");
				}
			}
		XMLWriter output=new XMLWriter(new FileWriter(new File("C:/xml/app-modify.xml")));	
		} catch (DocumentException e) {
			System.out.println(e.getMessage());
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}
	public static void main(String[] args) {
		Dom4jUpdate update = new Dom4jUpdate();
		update.modifyXML(new File("C:/Users/YF/eclipse-workspace-javaee/XML/src/XMLjiexi/app.xml"));
		
	}
}

  

 

 

posted on 2018-06-14 16:10  陌路lui  阅读(186)  评论(0编辑  收藏  举报