XML文件解析

简单的了解一下XML解析的集中方式,将学习笔记记录下来

  1. DOM解析XML
  2. SAX解析XML
  3. StAX解析XML

例如如下的一个XML文件(book.xml):

<?xml version="1.0" encoding="UTF-8"?>
<books>
	<book year="2000">
		<title>Snow Crash</title>
		<author>Neal Stephenson</author>
		<publisher>Spectra</publisher>
		<isbn>0553380958</isbn>
		<price>14.95</price>
	</book>
	<book year="2005">
		<title>Burning Tower</title>
		<author>Larry Niven</author>
		<author>Jerry Pournelle</author>
		<publisher>Pocket</publisher>
		<isbn>0743416910</isbn>
		<price>5.99</price>
	</book>
	<book year="1995">
		<title>Zodiac</title>
		<author>Neal Stephenson</author>
		<publisher>Spectra</publisher>
		<isbn>0553573862</isbn>
		<price>7.62</price>
	</book>
	<!-- more books -->
</books>

DOM

DOM是基于树形结构的XML解析方式,它会将整个XML文档读入到内存并构建一个DOM树,基于这颗树形结构对各个节点(Node)进行操作。XML文档中的每个成分都是一个节点:整个文档是一个文档节点,每个XML标签对应一个元素节点,包含在 XML标签中的文本是一个文本节点,每一个XML属性是一个属性节点,注释属于注释节点。

DOM解析的方式最主要的好处是易于编程,可以根据需求在树形结构的各节点之间导航。例如导航到当前节点的父节点、兄弟节点、子节点等都是比较方便的,这样就可以轻易地获取到自己需要的数据,也可以很容易的添加和修改树中的元素。因为整个XML文档加载到内存中并构造成树形结构,当XML文档较大时,会造成较大的资源消耗

首先使用DOM解析book.xml:

package ssm.pojectTest.parseXML.DOM;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * 使用DOM解析XML
 * @author msi
 * @date 2019年4月27日
 */
public class DOMTest {
	public static void main(String [] args) {
		// 1.创建DocumentBuilderFactory对象
		DocumentBuilderFactory a = DocumentBuilderFactory.newInstance();
		try {
			// 2.创建DocumentBuilder对象
			DocumentBuilder builder = a.newDocumentBuilder();
			// 3.通过Document对象的parse方法返回一个Document对象
			Document document = builder.parse("src/test/java/ssm/pojectTest/parseXML/book.xml");
			// 4.通过Document对象的getElementsByTagName()返根节点的一个list集合
			NodeList bookList = document.getElementsByTagName("book");
			// book节点的个数(这里是3)
			System.out.println("bookList.getLength():" + bookList.getLength());
			
			for (int i = 0; i < bookList.getLength(); i++) {
				// 循环遍历获取每一个book 
				Node book = bookList.item(i);
				// 获取节点的所有属性(在这里就是book元素的所有属性)
				NamedNodeMap map = book.getAttributes();
				
				for (int j = 0; j < map.getLength(); j ++) {
					Node node = map.item(j);
					//通过Node对象的getNodeName()和getNodeValue()方法获取属性名和属性值
					System.out.println(node.getNodeName() + ":" + node.getNodeValue() + "--" + node.getNodeType());
				}
				// 解析book节点的子节点(在这里就是获取当前循环中的book节点的子元素)
				NodeList childList = book.getChildNodes();
				//System.out.println("childList.getLength():" + childList.getLength());
				for (int t = 0; t < childList.getLength(); t++) {
					 // 区分出text类型的node以及element类型的node 
					if (childList.item(t).getNodeType() == Node.ELEMENT_NODE) {
						// getNodeNmae()用于得到子节点名,getTextContext()用于得到子节点的文本内容
						System.out.println(childList.item(t).getNodeName()+"===" + childList.item(t).getTextContent());
					}
				}
				
				
			}
			
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

 

SAX

SAX是基于事件模型的XML解析方式,它并不需要将整个XML文档加载到内存中,而只需将XML文档的一部分加载到内存中,即可开始解析,在处理过程中并不会在内存中记录XML中的数据,所以占用的资源比较小。当程序处理过程中满足条件时,也可以立即停止解析过程,这样就不必解析剩余的XML内容。

当SAX解析器解析到某类型节点时,会触发注册在该类型节点上的回调函数,开发人员可以根据自己感兴趣的事件注册相应的回调函数。一般情况下,开发人员只需继承SAX提供的DefaultHandler基类,重写相应事件的处理方法并进行注册即可。事件是由解析器产生并通过回调函数发送给应用程序的,这种模式我们也称为“推模式”。

SAX的缺点也非常明显,因为不存储XML的文档结构,所以需开发人员自己负责维护业务逻辑涉及的多层节点之间的关系,维护节点间的关系复杂度高,工作量也较大,另一方面,因为是流式处理,所以处理过程只能从XML文档开始向后单向进行,无法像DOM方式那样,自由导航到之前处理过的节点上重新处理,也无法支持Xpath。SAX没有提供撰写XML文档的功能

使用SAX解析XML:

一。首先需要一个继承了DefaultHandler的实现类,重写startDocument(),endDocument(),startElement(),endElement(),characters()。

例如:SaxHandler.java

package ssm.pojectTest.parseXML.SAX;

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

/**
 * 
 * @author msi
 * @date 2019年4月27日
 */
public class SaxHandler extends DefaultHandler{

	@Override
	public void startDocument() throws SAXException {
		System.out.println("…………开始解析文档…………\n");
		System.out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		super.startDocument();
	}

	@Override
	public void endDocument() throws SAXException {
		System.out.println("\n…………结束解析文档…………");
		super.endDocument();
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		
		System.out.print("<" + qName);
		
		if (attributes != null) {
			for (int i = 0; i < attributes.getLength(); i ++) {
				System.out.print(" " + attributes.getQName(i) + "=\"" + attributes.getValue(i) + "\"");
			}
		}
		
		System.out.print( ">");
		super.startElement(uri, localName, qName, attributes);
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		System.out.println("</" + qName + ">");
		super.endElement(uri, localName, qName);
	}

	/* 
	*  此方法有三个参数
    * ch是传回来的字符数组,其包含元素内容
    * start和length分别是数组的开始位置和结束位置 
    */
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		String content = new String(ch, start, length);
		System.out.print(content);
		super.characters(ch, start, length);
	}

}

使用SAX解析XML:SAXTest.java

package ssm.pojectTest.parseXML.SAX;

import java.io.File;
import java.io.IOException;

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

import org.xml.sax.SAXException;

public class SAXTest {
	public static void main(String [] args) {
		// 1.实例化SAXParserFactory对象
		SAXParserFactory factory = SAXParserFactory.newInstance();
		// 2.创建解析器
		try {
			SAXParser parser = factory.newSAXParser();
			// 3. 获取需要解析的文档
			File f = new File("src/test/java/ssm/pojectTest/parseXML/book.xml");
			SaxHandler handler = new SaxHandler();
			parser.parse(f,handler);
		} catch (ParserConfigurationException e) {
			
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}

结束,目前就对这两个解析方式进行了简单查阅,还有StAX.以后有机会在介绍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值