`
左手边
  • 浏览: 96940 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

xml常用四种解析方式优缺点的分析

    博客分类:
  • xml
 
阅读更多

      最近用得到xml的解析方式,于是就翻了翻自己的笔记同时从网上查找了资料,自己在前人的基础上总结了下,贴出来大家分享下。

首先介绍一下xml语言:

可扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。

xml的语法:

XML 分为两部分:头信息,主体信息

头信息是用来描述 XML 的一些属性,例如:版本,编码等,还可以提供 XML 显示的样式,和 dtd 编写格式。

主体信息中包含的是 XML 的具体数据。

 

头信息的语法:

<?xml version =”1.0” encoding =”GBK” ?>

其中 version 是必须加的,而 encoding 可以不写,则默认编码是 ISO8859-1 ,不支持中文。

除了这个功能外,头信息还可以进行编写格式的规定,通过 dtd xsd 文件。

头信息还支持样式表的导入,允许通过样式表控制 XML 的显示。

这样可以使用 XML+ CSS 完成页面的显示,通过这种形式完成 MVC 中的 View 层:

优点:代码的安全性很高,可以很容易的替换模板。

缺点:开发成本太高

主体信息 就是由三种节点组成的,节点之间存在父与子的关系,注意的点:

  一个节点只能有一个父节点,如果没有父节点,该节点称为根节点。

  一个节点可以有多个子节点。只有元素节点可以拥有子节点。

  元素节点的标记必须成对出现,或直接结束。

特殊字符必须转义。依据字符所处的位置是否对 XML 格式造成影响来决定是否进行转义

根节点只能有一个

xml常用的四种解析方式:

1)DOM(Document Object Model)

文档对象模型分析方式。以层次结构(类似于树型)来组织节点和信息片段,映射XML文档的结构,允许获取和操作文档的任意部分。是W3C的官方标准。

优点:
1、允许应用程序对数据和结构做出更改。
2、访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。

缺点:
1、通常需要加载整个XML文档来构造层次结构,消耗资源大

2)SAX(Simple API for XML)

流模型中的推模型分析方式。通过事件驱动,每发现一个节点就引发一个事件,通过回调方法完成解析工作,解析XML文档的逻辑需要应用程序完成。

优点:
1、不需要等待所有数据都被处理,分析就能立即开始。
2、只在读取数据时检查数据,不需要保存在内存中。
3、可以在某个条件得到满足时停止解析,不必解析整个文档。
4、效率和性能较高,能解析大于系统内存的文档。

缺点:
1、需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),使用麻烦。
2、单向导航,很难同时访问同一文档的不同部分数据,不支持XPath。

3)JDOM(Java-based Document Object Model)

Java特定的文档对象模型。自身不包含解析器,使用SAX。

优点:
1、使用具体类而不是接口,简化了DOM的API。
2、大量使用了Java集合类,方便了Java开发人员。

缺点:
1、没有较好的灵活性。
2、性能较差。

4)DOM4J(Document Object Model for Java)

简单易用,采用Java集合框架,并完全支持DOM、SAX和JAXP。

优点:
1、大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。
2、支持XPath。
3、有很好的性能。

缺点:
1、大量使用了接口,API较为复杂。

下面把四种解析方式的代码贴一下,首先是DOM方式

public class DOMXml {
	
	public static void createXML(String outputPath) {
		// 建立Document对象
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// 创建DocumentBuilder
		try {
			DocumentBuilder db = factory.newDocumentBuilder();
			// 创建Document,建立新的对象
			Document doc = db.newDocument();

			// 建立各个节点
			// 元素节点
			Element allplus = doc.createElement("allplus");
			
			Element areaplus = doc.createElement("areaplus");
			Element id = doc.createElement("id");
			Element title = doc.createElement("title");
			// 创建文本节点
			Text idText = doc.createTextNode("1");
			Text titleText = doc.createTextNode("123");

			// 配置父子节点的关系
			id.appendChild(idText);
			title.appendChild(titleText);

			areaplus.appendChild(id);
			areaplus.appendChild(title);

			allplus.appendChild(areaplus);


			// allplus是根节点,应该设置为doc的子节点
			doc.appendChild(allplus);

			// 执行保存操作
			TransformerFactory tf = TransformerFactory.newInstance();

			Transformer t = tf.newTransformer();

			// 包装要保存的doc
			DOMSource source = new DOMSource(doc);
			// 设置输出流
			StreamResult sr = new StreamResult(new File(outputPath));

			// 设置输出的属性
			t.setOutputProperty("encoding", "UTF-8");
			// t.setOutputProperty("version", "1.0");

			// 输出
			t.transform(source, sr);

		} catch (DOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}


	public static void parseXML(String xmlPath) {
		
		/*优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
		 * 缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
		 * 使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。 
		 * 10M文档导致内存溢出	
		 */
		
		// 建立Document对象
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// 创建DocumentBuilder
		try {
			DocumentBuilder db = factory.newDocumentBuilder();
			// 创建Document,形成树型结构
			Document doc = db.parse(new File(xmlPath));
			// 先取得所有的data
			NodeList datas = doc.getElementsByTagName("data");
			// 循环取得每个data
			for (int i = 0; i < datas.getLength(); i++) {
				Node data = datas.item(i);
				// 由于直接取得第一个和最后一个不符合要求,因此使用取得全部子节点的方式
				NodeList actorInfos = data.getChildNodes();
				for (int j = 0; j < actorInfos.getLength(); j++) {
					Node actorInfo = actorInfos.item(j);
					NodeList allChild = actorInfo.getChildNodes();
					for (int t = 0; t < allChild.getLength(); t++) {
						//判断节点
						Node child = allChild.item(t);
						if (child.getNodeType() == Node.ELEMENT_NODE) {
							if (child.getNodeName().equals("id")) {
								//判断是否有孩子节点,然后再取值
								if(child.hasChildNodes()) {
									System.out.println(child.getFirstChild().getNodeValue());
								}
							}
							if (child.getNodeName().equals("name")) {
								//判断是否有孩子节点,然后再取值
								if(child.hasChildNodes()) {
									System.out.println(child.getFirstChild().getNodeValue());
								}
							}
						}
					}
				}
			}
		} 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();
		}

	}

	public static void main(String[] args) {
		parseXML("D:/actor_info.xml");
		createXML("d:/fxb.xml");
	}

 SAX解析方式

public class SAXXml 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();
		SAXXml handler = new SAXXml();
		parser.parse(xmlStream, handler);
		return handler.getBooks();
	}

	public List<Book> getBooks() {
		return books;
	}

	@Override
	public void startDocument() throws SAXException {
		books = new ArrayList<Book>();
	}

	@Override
	public 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
	}

	@Override
	public 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,这不是我们想要的。
		 */
	}

	@Override
	public 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));
			}
		}
	}

	public static void main(String args[]) {
		
		SAXXml handler = new SAXXml();

		// 定义SUN自带解析对象
		SAXParser parser;
		try {
			parser = SAXParserFactory.newInstance().newSAXParser();
			parser.parse(new File("D:/book.xml"), 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();
		}
		List<Book> books = handler.getBooks();
		for (Book book : books) {
			System.out.println(book.toString());
		}
	}

 JDOM解析方式

public class JDOMXml {
	
	public static void createXML(String outputPath) {
		// 先建立Document对象
		Document doc = new Document();
		// 建立元素节点
		Element allplus = new Element("allplus");

		try {
			// 建立多个Element
			Element areaplus = new Element("areaplus");
			Element id = new Element("id");
			Element title = new Element("title");
			// 设置节点内容
			id.addContent("id");
			title.addContent("title");
			// 设置父子节点关系
			areaplus.addContent(id);
			areaplus.addContent(title);
			allplus.addContent(areaplus);
			// 设置根节点
			doc.setRootElement(allplus);

			// 使用IO流操作
			FileWriter writer = new FileWriter(new File(outputPath));

			// 定义输出对象
			XMLOutputter outputter = new XMLOutputter();
			// 设置编码
			outputter.setEncoding("UTF-8");
			// 输出
			outputter.output(doc, writer);
			writer.close();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static void parseXML(String xmlPath) {
		/*
		 * 10M文档导致内存溢出
		 */
		//完成解析功能。
		SAXBuilder builder = new SAXBuilder();
		try {
			Document doc = builder.build(new File(xmlPath));
			// 开始解析,取得根节点
			Element data = doc.getRootElement();
			// 取得所有的areaplus
			List<Element> actorInfos = data.getChildren("actor_info");
			if(actorInfos != null && actorInfos.size()>0) {
				for(Element actorInfo:actorInfos) {
					Element id = actorInfo.getChild("id");
					Element name = actorInfo.getChild("name");
					System.out.println(id.getTextTrim() + " --- " + name.getTextTrim());
				}
			}
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		parseXML("D:/actor_info.xml");
		createXML("d:/fdfdsf.xml");
	}

 DOM4J解析方式

package com.fxb.test;

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

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * 
 * @author hongliang.dinghl Dom4j 生成XML文档与解析XML文档
 */
public class DOM4JXml {

	public void createXml(String fileName) {
		Document document = DocumentHelper.createDocument();
		Element employees = document.addElement("data");
		Element employee = employees.addElement("actor_info");
		Element id = employee.addElement("id");
		id.setText("1");
		Element name = employee.addElement("name");
		name.setText("你好");
		Element message = employee.addElement("message");
		message.setText("你好吗");
		Element pic = employee.addElement("pic");
		pic.setText("123");
		Element sex = employee.addElement("sex");
		pic.setText("男");
		Element birthday = employee.addElement("birthday");
		pic.setText("19881212");
		try {
			Writer fileWriter = new FileWriter(fileName);
			XMLWriter xmlWriter = new XMLWriter(fileWriter);
			xmlWriter.write(document);
			xmlWriter.close();
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}

	}

	public void parserXml(String fileName) {
		File inputXml = new File(fileName);
		SAXReader saxReader = new SAXReader();
		try {
			Document document = saxReader.read(inputXml);
			Element data = document.getRootElement();
			for (Iterator i = data.elementIterator(); i.hasNext();) {
				Element actorInfo = (Element) i.next();
				//System.out.println(employee.getName() + "->" + employee.getText());
				for (Iterator j = actorInfo.elementIterator(); j.hasNext();) {
					Element child = (Element) j.next();
					System.out.println(child.getName() + ":" + child.getText());
				}
				System.out.println("=================");
			}
		} catch (DocumentException e) {
			System.out.println(e.getMessage());
		}
	}
	
	public static void main(String args[]) {
		DOM4JXml dom = new DOM4JXml();
		//dom.parserXml("d:/actor_info.xml");
		dom.createXml("d:/fxb.xml");
	}
}
 

 

 

4
2
分享到:
评论
1 楼 hecal 2012-08-11  
god,兄弟你的代码有个bug.
在你的SAX解析方式里,有一个小bug.其他的没看。

50.    @Override 
51.    public void characters(char[] ch, int start, int length) 
52.            throws SAXException { 
53.        if (preTag != null) { 
54.            String content = new String(ch, start, length); 
55.            if ("name".equals(preTag)) { 
56.                book.setName(book.getName() + content); 
57.            } else if ("price".equals(preTag)) { 
58.                book.setPrice(Float.parseFloat(content)); 
59.            } 
60.        } 
61.    } 

原因:当name是很长的文章的时候,就被切断了,结果出错了。

相关推荐

    android 三种xml解析方式整合

    在开发过程中,理解这三种解析方式的工作原理和优缺点,能帮助我们更好地处理XML数据,提高应用的性能和用户体验。同时,熟悉如何在代码中灵活运用和整合这些解析方式,也是Android开发中的重要技能。

    adroid解析XML三种方式——源码分析

    本篇文章将深入探讨Android解析XML的三种主要方法:DOM、SAX和Pull解析器,并结合源码进行分析,帮助开发者理解它们的工作原理和适用场景。 1. DOM解析: DOM(Document Object Model)解析器将整个XML文档加载到...

    四中最常用的XML文件解析总结.doc

    根据给定文件的信息,我们将深入探讨四种最常用的XML文件解析技术:DOM(Document Object Model)、SAX(Simple API for XML)、STAX(Streaming API for XML)以及DOM4j。 ### DOM解析 DOM是一种树型结构的数据...

    Java中四种XML解析技术

    ### Java中四种XML解析技术详解 #### 一、引言 在软件开发过程中,XML(Extensible Markup Language)作为一种常用的数据交换格式,在多种场景下都有着广泛的应用。对于Java开发者而言,掌握不同类型的XML解析方法...

    java解析xml及4种常用解析比较

    ### Java解析XML及四种常用解析方法比较 #### 一、DOM (JAXP Crimson解析器) **1.1 概念** DOM (Document Object Model) 是一种与平台和语言无关的标准,用于表示XML文档。它是由W3C组织定义的一个官方标准。DOM...

    android各种解析xml三种方式和json数据

    总结来说,XML解析在Android开发中主要涉及DOM、SAX和Pull三种方法,每种方法各有优缺点,应根据具体需求选择。而JSON数据通常借助于Gson或Jackson库,实现高效的数据交换。理解并熟练运用这些知识点,将有助于提升...

    android的xml文件的解析

    在Android开发中,XML文件广泛用于布局设计、配置...在实际项目中,还有一种基于SAX的拉式解析库——PULL解析器(Android提供的`XmlPullParser`),它在内存效率和灵活性之间找到了一个平衡点,也是常用的XML解析方法。

    XML解析代码

    这四种方法各有优缺点,DOM解析方便但占用内存大,SAX和Pull解析节省内存但编程相对复杂,JAXB则提供了对象与XML的直接映射,但可能不适合资源有限的移动环境。在实际开发中,应根据项目需求和资源限制选择合适的XML...

    XML解析jar

    在Java中,解析XML文件是常见的任务,本篇将详细讲解三种常用的XML解析器:DOM4J、SAX2R2以及JAXB。 1. DOM4J: DOM4J是一个强大的Java库,它提供了对XML的全面支持,包括读取、写入、修改和操作XML文档。DOM4J基于...

    Android 解析 XML 三种方法

    XML的解析方式有多种,其中SAX、DOM和PULL是Android平台常用的三种解析器。以下将详细解释这三种解析方法,并提供相关的实践应用场景。 1. SAX(Simple API for XML)解析器: SAX是一种基于事件驱动的解析方式,它...

    android的三种xml解析方式

    在Android开发中,XML(eXtensible Markup Language)是一种常用的数据存储和交换格式,用于定义应用程序的布局、配置和数据。...理解这三种解析方式及其优缺点,有助于提高Android应用的性能和效率。

    Android基础——XML数据的三种解析方式

    本篇文章将深入探讨XML在Android中的三种主要解析方式:DOM解析、SAX解析和Pull解析,帮助开发者更好地理解和运用这些方法。 1. DOM解析(Document Object Model) DOM解析器会将整个XML文档加载到内存中,形成一个...

    Android中三种解析XML的方式

    在Android开发中,XML(eXtensible Markup Language)是一种常用的数据存储和交换格式,用于存储结构化的数据。为了处理这些XML文档,Android提供...在处理XML时,理解这三种解析方式的优缺点和适用场景是非常重要的。

    iphone开发之xml解析

    在iOS开发中,XML(eXtensible Markup Language)是一种常用的数据交换格式,它具有结构化、可扩展性,使得不同系统间的数据交互变得简单。本篇将详细讲解iPhone开发中的XML解析技术。 首先,XML解析是将XML文档...

    Java更新XML的四种常用方法简介

    Java更新XML文档的方法主要包括四种,本文将探讨这些方法并分析其优缺点。首先,我们要了解JAXP(Java API for XML Processing),这是一个用于XML处理的Java编程接口,支持DOM、SAX和XSLT等标准。JAXP的可插拔层...

    Aandroid 解析xml参考文献

    在Android开发中,XML(eXtensible Markup Language)是一种常用的数据交换格式,它用于存储结构化数据。本文将深入探讨Android平台下解析XML的三种主要方法:SAX(Simple API for XML)、DOM(Document Object ...

    jsp实现XML解析文档

    在JSP中实现XML解析,主要有两种方式:DOM(Document Object Model)解析和SAX(Simple API for XML)解析。 **DOM解析**是一种将整个XML文档加载到内存中形成一棵树形结构的方法。DOM模型定义了一系列Java接口,...

Global site tag (gtag.js) - Google Analytics