Java--xml文件的解析

来源:互联网 发布:java小游戏制作教程 编辑:程序博客网 时间:2024/04/30 13:56

本文主要讲述两个xml的解析方式:DOM解析和SAX解析。

一、DOM解析步骤:

1.通过文档解析器的工厂对象DocumentBuilderFactory得到一个文档解析DocunmentBuilder对象builder

2.通过输入流对象is获取xml文件内容

3.通过解析器的parse方法解析输入流对象is,并转换成Document对象document

4.获取文档的根节点document.getDocumentElement();

5.判断是否有孩子节点

6.获取所有的子节点对象,并判断每个子节点对象的类型,以获取指定类型节点的数据

7.将获取节点中的值并赋给实体化对象

示例代码如下:

package www.csdn.net.activityg.xml;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Attr;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import www.csdn.net.activityg.domain.City;public class DOMXML {public List<City> domXml() {// 创建返回的集合对象List<City> cities = new ArrayList<City>();// 创建问文档解析器的工厂对象DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();try {// 得到文档解析器对象DocumentBuilder builder = builderFactory.newDocumentBuilder();// 获取输入流对象InputStream is = getClass().getClassLoader().getResourceAsStream("china.xml");// 通过解析器的parse方法 解析is对象,转换成 Document对象Document document = builder.parse(is);// 返回的是文档的跟节点Element rootElement = document.getDocumentElement();// 判断是否有孩子节点if (rootElement.hasChildNodes()) {// 获取所有的子节点NodeList nodeList = rootElement.getChildNodes();// 遍历子节点for (int i = 0; i < nodeList.getLength(); i++) {// 获取子节点对象Node node = nodeList.item(i);// 元素节点的类型值:1 文本类型的类型节点值:3 属性节点的类型值:2// 判断这个子节点是什么类型的子节点 文本节点 元素节点if (node.getNodeType() == Element.ELEMENT_NODE) {// 创建一个实体对象 保存元素节点值City city = new City();// 造型Element element = (Element) node;// 得到这个节点中的所有属性节点NamedNodeMap map = element.getAttributes();//-------------- 遍历属性节点开始-----------------------for (int j = 0; j < map.getLength(); j++) {// 获取具体的某个属性节点Attr attr = (Attr) map.item(j);// 具体判断if ("cityname".equals(attr.getNodeName())) {// 设置对象的属性值city.setCityName(attr.getNodeValue());} else if ("pyName".equals(attr.getNodeName())) {city.setPyName(attr.getNodeValue());} else if ("quName".equals(attr.getNodeName())) {city.setQuName(attr.getNodeValue());} else if ("state1".equals(attr.getNodeName())) {city.setState1(attr.getNodeValue());} else if ("state2".equals(attr.getNodeName())) {city.setState2(attr.getNodeValue());} else if ("stateDetailed".equals(attr.getNodeName())) {city.setStateDetailed(attr.getNodeValue());} else if ("tem1".equals(attr.getNodeName())) {city.setTem1(attr.getNodeValue());} else if ("tem2".equals(attr.getNodeName())) {city.setTem2(attr.getNodeValue());} else if ("windState".equals(attr.getNodeName())) {city.setWindState(attr.getNodeValue());}}//-------------------遍历属性节点的结束-------------------------------// 添加到集合中cities.add(city);}}}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return cities;}}

DOM的优势主要表现在:易用性强,使用DOM时,将把所有的XML文档信息都存于内存中,并且遍历简单,支持XPath,增强了易用性。

DOM的缺点主要表现在:效率低,解析速度慢,内存占用量过高,对于大文件来说几乎不可能使用。另外效率低还表现在大量的消耗时间,因为使用DOM进行解析时,将为文档的每个elementattributeprocessing-instrUCtioncomment都创建一个对象,这样在DOM机制中所运用的大量对象的创建和销毁无疑会影响其效率。

所以DOM解析适用于小型xml文档的解析。






二、SAX

SAX不像DOM那样建立一个完整的文档树,而是在读取文档时激活一系列事件,这些事件被推给事件处理器,然后由事件处理器提供对文档内容的访问。通过继承DefaultHandler,并重写其中的方法来实现对xml文档的解析。

SAX的优点在于内存消耗少,可以解析大文件。缺点在于Sax解析是按照xml文件的顺序一步一步的来解析,如果xml文档结构非常的复杂,则会给编程带来麻烦。

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.SAXException;import org.xml.sax.helpers.DefaultHandler;import com.xtlh.cn.entity.Book;public class SaxParseService extends DefaultHandler{private List<Book> books = null;private Book book = null;private String preTag = null;//作用是记录解析时的上一个节点名称public List<Book> getBooks(InputStream xmlStream) throws Exception{SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();SaxParseService handler = new SaxParseService();parser.parse(xmlStream, handler);return handler.getBooks();}public List<Book> getBooks(){return books;}@Overridepublic void startDocument() throws SAXException {books = new ArrayList<Book>();}@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {if("book".equals(qName)){book = new Book();book.setId(Integer.parseInt(attributes.getValue(0)));}preTag = qName;//将正在解析的节点名称赋给preTag}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {if("book".equals(qName)){books.add(book);book = null;}preTag = null;/**当解析结束时置为空。这里很重要,例如,当图中画3的位置结束后,会调用这个方法,如果这里不把preTag置为null,根据startElement(....)方法,preTag的值还是book,当文档顺序读到图中标记4的位置时,会执行characters(char[] ch, int start, int length)这个方法,而characters(....)方法判断preTag!=null,会执行if判断的代码,这样就会把空值赋值给book,这不是我们想要的。*/}@Overridepublic void characters(char[] ch, int start, int length) throws SAXException {if(preTag!=null){String content = new String(ch,start,length);if("name".equals(preTag)){book.setName(content);}else if("price".equals(preTag)){book.setPrice(Float.parseFloat(content));}}}}
代码来自http://www.iteye.com/topic/763895

三、DOM与SAX的区别

1.DOM把所有的XML文档信息都存于内存中

2.Sax无需一次把xml文件加载到内存中,采用的事件驱动的操作

3.应用场景不一样,dom适合复杂结构小型xml文档,sax适用于简单结构大型xml。

4.dom可以直接获取某个节点,Sax只能按步骤读取。

0 0
原创粉丝点击