xml的两种解析方式

             这里讲解xml的两种解析方式:dom解析和sax解析。

1.简要说明

         dom解析
(1)将整个XML使用类似树的结构保存在内存中,再对其进行操作。

(2)是 W3C 组织推荐的处理 XML 的一种方式。

(3)需要等到XML完全加载进内存才可以进行操作。

(4)缺点:解析过程比较慢,需要将整个文档都解析完成后才能进行操作,耗费内存,当解析超大的XML时慎用。

(5)优点:可以方便的对xml进行增删该查操作;只需解析一次拿到dom对象后可以重复使用对象减少解析次数。

         sax解析

          (1)逐行扫描XML文档,当遇到标签时触发解析处理器,采用事件处理的方式解析xml。
          (2)(Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。
          (3)在读取文档的同时即可对xml进行处理,不必等到文档加载结束,相对快捷
          (4)优点不需要加载进内存,因此不存在占用内存的问题,可以解析超大XML
          (5)缺点只能用来读取XML中数据,无法进行增删改

          

          基于这两种解析思想市面上就有了很多的解析api:
  (1)sun jaxp     既有dom方式也有sax方式,并且这套解析api已经加入到j2se的规范中,意味这不需要导入任何第三方开发包就可以直接使用这种解析方式.但是这种解析方式效率低下,没什么人用.
          (2)dom4j        可以使用dom方式高效的解析xml.
          (3)pull             Android开发里面会用的。

注:(1)使用dom4j开发包:(文件名:dom4j-1.6.1.jar)
        (2)导入开发包,通常只需要导入核心包(dom4j-1.6.1.jar)就可以了,如果在使用的过程中提示少什么包到lib目录下在导入缺少的包即可。

        (3)导入过程:

①在java工程中新建”lib“文件夹;

②copy包到此文件夹中;

③右键此包,选择"Build Path"→”Add to path“即可。

2.java代码示例

sax解析:
public class SaxDemo1 {

	public static void main(String[] args) throws Exception {
		// 1.获取解析器工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		// 2.通过工厂获取sax解析器
		SAXParser parser = factory.newSAXParser();
		// 3.获取读取器
		XMLReader reader = parser.getXMLReader();
		// 4.注册事件处理器  设置读取器的事件处理器
		reader.setContentHandler(new MyContentHandler2());
		// 5.解析xml
		reader.parse("book.xml");
	}

}

// 适配器模式
//DefaultHandler是一个类,他默认实现了ContentHandler接口,
//并提供了其中所有方法的空实现,我们可以自己写一个类继承这个类,复写其中我们需要使用到的方法。就不必实现所有的方法了,好用!!!
class MyContentHandler2 extends DefaultHandler {
	private String eleName = null;
	private int count = 0;

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		this.eleName = qName;

	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if ("书名".equals(eleName)&& (++count==2)) {     //打印第二本书名
			System.out.println(new String(ch, start, length));
			
		}

	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		this.eleName= null;
	}
}

class MyContentHandler implements ContentHandler {
        //我们需要实现ContentHandler所有方法
	@Override
	public void startDocument() throws SAXException {
		System.out.println("文档解析开始了.........");

	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes atts) throws SAXException {
		System.out.println("发现了开始标签:" + qName);

	}

	@Override
	public void characters(char[] ch, int start, int length)      //char[] ch指的是整个文档,不是当前这个字符数组。
			throws SAXException {
		System.out.println(new String(ch, start, length));

	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		System.out.println("发现了结束标签:" + qName);

	}

	@Override
	public void endDocument() throws SAXException {
		System.out.println("文档解析结束了.........");

	}

	@Override
	public void endPrefixMapping(String prefix) throws SAXException {

	}

	@Override
	public void ignorableWhitespace(char[] ch, int start, int length)
			throws SAXException {

	}

	@Override
	public void processingInstruction(String target, String data)
			throws SAXException {

	}

	@Override
	public void setDocumentLocator(Locator locator) {

	}

	@Override
	public void skippedEntity(String name) throws SAXException {

	}

	@Override
	public void startPrefixMapping(String prefix, String uri)
			throws SAXException {

	}
}

dom解析(使用了dom4j)
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.List;


import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;

public class Dom4jDemo2 {

	//改 
	@Test
	public void update() throws Exception{
		SAXReader reader = new SAXReader();
		Document dom = reader.read("book.xml");
		Element root = dom.getRootElement();
		
		root.element("书").element("特价").setText("24.99");
		
		XMLWriter writer =  new XMLWriter(new FileOutputStream("book.xml"), OutputFormat.createPrettyPrint());
		writer.write(dom);
		writer.close();
	}
	
	//增加
	@Test
	public void add() throws Exception {
		//1.获取dom4j解析器
		SAXReader reader = new SAXReader();
		//2.获取document对象dom
		Document dom = reader.read("book.xml");
		//3.获取根节点对象
		Element root = dom.getRootElement();
		//4.凭空创建节点<特价>,并设置标签体内容
		Element newPrice = DocumentHelper.createElement("特价");
		newPrice.setText("25.00");
		root.element("书").add(newPrice);
		
		//将内存中的dom树写到xml文件中。从而使其数据更新。
		
		
		/*①第一种方法
		FileWriter fw = new FileWriter("book.xml");
		dom.write(fw);
		
		fw.flush();
		fw.close();*/
		
		
		//②第二种方法
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("book.xml"), OutputFormat.createPrettyPrint());
		xmlWriter.write(dom);
		xmlWriter.close();
		
	}
	
	
	
	//查询第二本书的名字
	@Test
	public void find() throws Exception {

		SAXReader reader = new SAXReader();
		Document dom = reader.read("book.xml");
		Element root = dom.getRootElement();

		List<Element> list = root.elements();
		Element book2Ele = list.get(1);
		System.out.println(book2Ele.element("书名").getText());
	}
	
	//删除
	@Test
	public void delete() throws Exception{
		SAXReader reader = new SAXReader();
		Document dom = reader.read("book.xml");
		Element root = dom.getRootElement();
		
		Element newPrice = root.element("书").element("特价");
		
		newPrice.getParent().remove(newPrice);
		
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("book.xml"), OutputFormat.createPrettyPrint());
		xmlWriter.write(dom);
		xmlWriter.close();
		
	}

	
	//对属性的操作
	@Test
	public void attributeTest() throws Exception{
		
		SAXReader reader = new SAXReader();
		Document dom = reader.read("book.xml");
		Element root = dom.getRootElement();
		
		
		//****************增加属性********************************************
		/*
		List<Element> bookName = root.elements("书");
		//给第二本书增加属性 
		bookName.get(1).addAttribute("出版社", "北京大学出版社");
		//给第二本书的“书名”增加属性
		bookName.get(1).element("书名").addAttribute("语言", "中文");
		*/
		//*******************************************************************
		
		//****************查询属性********************************************
		/*
		List<Element> bookName = root.elements("书");
		//查询第二本书出版社属性 
		String publisherText = bookName.get(1).attribute("出版社").getText();
		System.out.println(publisherText);
		*/
		//*******************************************************************
		

		//****************更新属性********************************************
		/*
		List<Element> bookName = root.elements("书");
		//修改第二本书出版社属性 
		bookName.get(1).attribute("出版社").setText("人民教育出版社");
		
		*/
		//*******************************************************************
		
		//****************删除属性********************************************
		
		List<Element> bookName = root.elements("书");
		//删除第二本书出版社属性 
		Attribute publisher = bookName.get(1).attribute("出版社");
		publisher.getParent().remove(publisher);
		
		
		//*******************************************************************
		
		
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("book.xml"), OutputFormat.createPrettyPrint());
		xmlWriter.write(dom);
		xmlWriter.close();
		
	}

}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值