论坛首页 Java企业应用论坛

Java Dom解析xml

浏览 111496 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (9) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-09-15  

Dom解析是将xml文件全部载入,组装成一颗dom树,然后通过节点以及节点之间的关系来解析xml文件,下面结合这个xml文件来进行dom解析。

<?xml version="1.0" encoding="UTF-8"?>
<books>
	<book id="12">
		<name>thinking in java</name>
		<price>85.5</price>
	</book>
	<book id="15">
		<name>Spring in Action</name>
		<price>39.0</price>
	</book>
</books>

 然后结合一张图来发现dom解析时需要注意的地方



 

在这里当我们得到节点book时,也就是图中1所画的地方,如果我们调用它的getChildNodes()方法,大家猜猜它的子节点有几个?不包括它的孙子节点,thinking in java这种的除外,因为它是孙子节点。它总共有5个子节点,分别是图中2、3、4、5、6所示的那样。所以在解析时,一定要小心,不要忽略空白的地方。

然后看代码来解析book.xml文件

DomParseService.java

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.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;

import com.xtlh.cn.entity.Book;

public class DomParseService {
	public List<Book> getBooks(InputStream inputStream) throws Exception{
		List<Book> list = new ArrayList<Book>();
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse(inputStream);
		Element element = document.getDocumentElement();
		
		NodeList bookNodes = element.getElementsByTagName("book");
		for(int i=0;i<bookNodes.getLength();i++){
			Element bookElement = (Element) bookNodes.item(i);
			Book book = new Book();
			book.setId(Integer.parseInt(bookElement.getAttribute("id")));
			NodeList childNodes = bookElement.getChildNodes();
//			System.out.println("*****"+childNodes.getLength());
			for(int j=0;j<childNodes.getLength();j++){
				if(childNodes.item(j).getNodeType()==Node.ELEMENT_NODE){
					if("name".equals(childNodes.item(j).getNodeName())){
						book.setName(childNodes.item(j).getFirstChild().getNodeValue());
					}else if("price".equals(childNodes.item(j).getNodeName())){
						book.setPrice(Float.parseFloat(childNodes.item(j).getFirstChild().getNodeValue()));
					}
				}
			}//end for j
			list.add(book);
		}//end for i
		return list;
	}
}

 Book.java用来组装数据和盛放数据

public class Book {
	private int id;
	private String name;
	private float price;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	@Override
	public String toString(){
		return this.id+":"+this.name+":"+this.price;
	}
}

 

测试使用单元测试如下ParseTest.java

public class ParseTest extends TestCase{

	public void testDom() throws Exception{
		InputStream input = this.getClass().getClassLoader().getResourceAsStream("book.xml");
		DomParseService dom = new DomParseService();
		List<Book> books = dom.getBooks(input);
		for(Book book : books){
			System.out.println(book.toString());
		}
	}
}

 原打算将dom解析和Sax解析写在一起的,没想到超过字数了,只能分开写了,如果对Sax解析感兴趣,可以到下面的链接去看:http://sinye.iteye.com/blog/763895

  • 大小: 31.5 KB
   发表时间:2010-09-16  
DOM用来解析解析配置文件还可以,来解析业务报文之类的就吃不消了

支持StAX
0 请登录后投票
   发表时间:2010-09-17  
for(int i=0;i<bookNodes.getLength();i++),这种写法相当不好啊,每次都是算的,如果book节点多了多性能的消耗相当严重,int length = bookNodes.getLength(),for(int i=0;i<length;i++)
0 请登录后投票
   发表时间:2010-09-17  
darwintest 写道
for(int i=0;i<bookNodes.getLength();i++),这种写法相当不好啊,每次都是算的,如果book节点多了多性能的消耗相当严重,int length = bookNodes.getLength(),for(int i=0;i<length;i++)

其实这里的消耗还是可以的,Dom解析真正消耗严重的是在它载入xml文件建立Dom树的过程,如果xml文件越大,树级结构越深,消耗就越大!
0 请登录后投票
   发表时间:2010-09-17  
freish 写道
DOM用来解析解析配置文件还可以,来解析业务报文之类的就吃不消了

支持StAX

的确,一般还是用Sax或者Pull解析!
0 请登录后投票
   发表时间:2010-09-17  
darwintest 写道
for(int i=0;i<bookNodes.getLength();i++),这种写法相当不好啊,每次都是算的,如果book节点多了多性能的消耗相当严重,int length = bookNodes.getLength(),for(int i=0;i<length;i++)



如果让你来设计你会把bookNodes.getLength()设计成每次都去算吗?
这个朋友有没有去看过源码?就像ArrayList.size(),你会每次都算字的大小吗?
去看看源码吧!
0 请登录后投票
   发表时间:2010-12-09  
jwinder 写道
darwintest 写道
for(int i=0;i<bookNodes.getLength();i++),这种写法相当不好啊,每次都是算的,如果book节点多了多性能的消耗相当严重,int length = bookNodes.getLength(),for(int i=0;i<length;i++)



如果让你来设计你会把bookNodes.getLength()设计成每次都去算吗?
这个朋友有没有去看过源码?就像ArrayList.size(),你会每次都算字的大小吗?
去看看源码吧!



说的好,我认为编译器肯定会对这种写法进行优化的... 他的意思可能是调用方法的开销肯定比直接读取变量的开销大..


0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics