1 dom解析XML文件简介
在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的应用价值的。
2 需要解析的XML文档
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="cooking">
<title>Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="children">
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title>XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="web" cover="paperback">
<title>Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
要严格区分XML文档树中的根节点与根元素节点:
文档(根节点)和根元素节点是两回事。
根节点代表整个文档,是我们解析XML文档的入口,通过它获取到Document对象;
根元素节点代表XML文档的根元素,必须要在获得Document对象之后才能一层一层地去访问它的元素。
最常见的节点类型:
元素:元素是XML的基本构建。
元素可以有其他元素、文本节点或两者兼有来作为其子节点。
元素节点还是可以有属性的唯一类型的节点。
属性:属性节点包含关于元素节点的信息,但实际上,不认为它是元素的子节点。
文本:确切来讲,文本节点是文本。它可以包含许多信息或仅仅是空白。
文档(根节点):文档节点是整个文档中所有其他节点的父节点。(根节点不等于根元素节点)。
较不常见的节点类型:CDATA、注释、处理指令。
3 解析xml文件代码
在DOM接口规范中,有四个基本的接口:Document, Node, NodeList, NamedNodeMap。
Document:
Document接口是对文档进行操作的入口,它是从Node接口继承过来的。
Node:
Node接口是其他大多数接口的父类。
在DOM树中,Node接口代表了树中的一个节点。
NodeList:
NodeList接口是一个节点的集合,它包含了某个节点中的所有子节点。
它提供了对节点集合的抽象定义,并不包含如何实现这个节点集的定义。
NodeList用于表示有顺序关系的一组节点,比如某个节点的子节点序列。
在DOM中,NodeList的对象是live的,对文档的改变,会直接反映到相关的NodeList对象中。
NamedNodeMap:
NamedNodeMap接口也是一个节点的集合,通过该接口,可以建立节点名和节点之间的一一映射关系,从而利用节点名可以直接访问特定的节点,这个接口主要用在属性节点的表示上。尽管NamedNodeMap所包含的节点可以通过索引来进行访问,但是这只是提供了一种枚举方法,NamedNodeMap所包含的节点集中节点是无序的。与NodeList相同,在DOM中,NamedNodeMap对象也是live的。
book.java
package com.wnq.sk.domXML02;
public class Book
{
// 与books.xml中的节点对应
private String category;
private String titleLang;
private String title;
private String author;
private Integer year;
private Double price;
public String getCategory()
{
return category;
}
public void setCategory(String category)
{
this.category = category;
}
public String getTitleLang()
{
return titleLang;
}
public void setTitleLang(String titleLang)
{
this.titleLang = titleLang;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getAuthor()
{
return author;
}
public void setAuthor(String author)
{
this.author = author;
}
public Integer getYear()
{
return year;
}
public void setYear(Integer year)
{
this.year = year;
}
public Double getPrice()
{
return price;
}
public void setPrice(Double price)
{
this.price = price;
}
@Override
public String toString()
{
return "Book [category=" + category + ", titleLang=" + titleLang + ", title=" + title + ", author=" + author
+ ", year=" + year + ", price=" + price + "]";
}
}
ReadXMLFile.java
package com.wnq.sk.domXML02;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class ReadXMLFile
{
// 读取books.xml的值,并存入到List中
public static void main(String[] args)
{
String fileName = "books.xml";
List<Book> books = readXMLFile(fileName);
for (Book book : books)
{
System.out.println(book.toString());
}
}
public static List<Book> readXMLFile(String fileName)
{
List<Book> lists=new ArrayList<Book>();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
try
{
DocumentBuilder documentBuilder = dbFactory.newDocumentBuilder();
try
{
Document document=documentBuilder.parse(fileName);
NodeList bookList = document.getElementsByTagName("book");
for (int i = 0; i < bookList.getLength(); i++)
{
Node bookNode = bookList.item(i);
if (bookNode.getNodeType() == Node.ELEMENT_NODE)
{
Element bookElement = (Element)bookNode;
Book book = new Book();
book.setCategory(bookElement.getAttribute("category"));
// 因为<title lang=""></title>里面带有属性
Element titleElement = (Element)bookElement.getElementsByTagName("title").item(0);
book.setTitle(titleElement.getTextContent());
book.setTitleLang(titleElement.getAttribute("lang"));
// book的author属性是一个集合
NodeList authorList = bookElement.getElementsByTagName("author");
String author = "";
for (int j = 0; j < authorList.getLength(); j++)
{
author = author + authorList.item(j).getTextContent() + "/";
}
author = author.substring(0, author.length() - 1);
book.setAuthor(author);
book.setYear(Integer.valueOf(bookElement.getElementsByTagName("year").item(0).getTextContent()));
book.setPrice(Double.valueOf(bookElement.getElementsByTagName("price").item(0).getTextContent()));
lists.add(book);
}
}
}
catch (SAXException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
catch (ParserConfigurationException e)
{
e.printStackTrace();
}
return lists;
}
}
运行结果:
该贴被蜀山战纪编辑于2016-2-1 10:46:57