最近在学习XML解析,在此做了一个小的demo,跟大家分享,有什么问题欢迎指出!!
Book.java
//保存 book的属性的类
public class Book {
private String id; // 书籍编号
private String name; //书名
private String author; //作者
private int year; //出版时间
private String kinds; // 书籍种类
public Book(String id, String name, String author, int year, String kinds) {
this.id = id;
this.name = name;
this.author = author;
this.year = year;
this.kinds = kinds;
}
public Book() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String getKinds() {
return kinds;
}
public void setKinds(String kinds) {
this.kinds = kinds;
}
@Override
public String toString() {
return "Book{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", author='" + author + '\'' +
", year=" + year +
", kinds='" + kinds + '\'' +
'}';
}
}
DOMParser.java
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.util.*;
import org.w3c.dom.NodeList;
public class DOMParser {
private static final String FILENAME = "bookstore.xml";//需要解析的静态xml文件
private static Map<String,String> book; //保存书籍的键值对映射的集合
private static List<Map<String,String>> books ; //保存所有book项的列表
private static List<Book> bookList=new ArrayList<>();; //初始化bookList,类型是书的实体类的列表
/*XML的DOM解析器*/
private void myParser() throws ParserConfigurationException, IOException, SAXException {
// 创建 DocumentBuilderFactory对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
// 创建Document对象,解析 FILENAME
Document document = db.parse(FILENAME);
/* 参考的bookstore.xml的模板:
<book id="b1">
<name>android移动开发基础</name>
<author>黑马程序员</author>
<year>2015</year>
<kinds>IT</kinds>
</book>
*/
// 解析XML,获取到书的集合
NodeList bookList = document.getElementsByTagName("book");
books = new ArrayList<Map<String,String>>(); // 初始化该列表
//下面需要遍历书的集合
for (int i = 0; i < bookList.getLength(); i++) {
book = new HashMap<>(); //初始化书的键值对的集合
System.out.println("--------------------第"+(i+1)+"几本书遍历开始----------------------");
//遍历获取其中的单本书
Node bookNode = bookList.item(i);
//获取book节点属性
NamedNodeMap nnm = bookNode.getAttributes();
//获得book节点属性的长度
int length = nnm.getLength();
System.out.print("第"+(i+1)+"本书的属性有"+length+"条 ");
//对该标签的各属性遍历,获得键和值
for (int j = 0; j < length; j++) {
//item()可以得到单个属性
Node node = nnm.item(j);
String nodeName = node.getNodeName();//获得属性名
String nodeValue = node.getNodeValue(); //获得属性值
System.out.println(nodeName+" : "+nodeValue);
book.put(nodeName, nodeValue); //将 id 属性名、属性值写到书的键值对的集合中去
}
// System.out.println("------------------分割符----------------------");
/*获取节点的子节点,同上面的getElementByTagName()返回值相同,为NodeList类型*/
NodeList childList = bookNode.getChildNodes();
System.out.println("第"+(i+1)+"本书共有"+childList.getLength()+"条子属性");
System.out.println("其中元素属性有:");
for (int k = 0; k < childList.getLength(); k++) {
Node node2 = childList.item(k); // 遍历各子属性
String nodeName2 = node2.getNodeName(); //获取子属性名
// String nodeValue2 = node2.getNodeValue();// 形如 “<name>android移动开发基础</name>”,此方法返回null,不采用
String nodeValue2 = node2.getTextContent(); //可以获取到content ,即标签内的"android移动基础"文字
//上面方法注意如果里面有其他文本内容,需要另外再解析,否则,返回值可能包含你不需要的其他文本内容
book.put(nodeName2, nodeValue2); //将遍历到的所有book标签下子属性的属性名、属性值写到书的键值对的集合中去
if (node2.getNodeType()==Node.ELEMENT_NODE) { //这个判断过滤了其他的Node类型,只取需要的Element类型
System.out.println(nodeName2+" : "+nodeValue2);
}
}
books.add(book); //往保存所有book项的列表中添加已经put值的book项
System.out.println("--------------------第"+(i+1)+"几本书遍历结束----------------------\n\n");
}
}
/**
* map -> entity,即把book项中的键值对的值写到 Book的实体类(Entity),保存以便于开发
* @param bookMap 保存book的键值对的集合
* @return 已经转换好的 Book类实例
* @throws NullPointerException 空指针错误,可能在bookMap未初始化的情况下
*/
private static Book convertToEntity(Map<String, String> bookMap)throws NullPointerException{
if(bookMap!=null) {
Book b = new Book();
b.setId(bookMap.get("id"));
b.setName(bookMap.get("name"));
b.setAuthor(bookMap.get("author"));
b.setYear(Integer.valueOf(bookMap.get("year"))); //参数需要int类型,Integer.valueOf(String)将 String->int
b.setKinds(bookMap.get("kinds"));
return b;
}else{
throw new NullPointerException("书籍键值对映射指针为空");
}
}
/**
* 往书的实体类的列表中添加书的实体类
* @return 添加完Book类对象的实体类列表
*/
private static List<Book> getBooksCollection(){
int index =0; //书的实体类列表的下标
for(Map<String,String> book:books) {
Book b = DOMParser.convertToEntity(books.get(index++));
bookList.add(b);
}
return bookList;
}
public static void main(String[] args) {
try {
DOMParser parser = new DOMParser(); //实例化xml解析器
parser.myParser(); // 调用解析 XML的方法,打印出结果
bookList = DOMParser.getBooksCollection(); //调用DOMParser静态方法获得书的实体类的列表
//遍历书的实体类的列表,打印出各个Book实体类的情况 ,这里我重写了Book类的toString()方法
for (int i = 0; i < bookList.size(); i++) {
Book b = bookList.get(i); //取出Book类实例
System.out.println(b.toString());
}
} catch (ParserConfigurationException | IOException | SAXException e) {
e.printStackTrace();
}
}
}
bookstore.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book id="b1">
<name>android移动开发基础</name>
<author>黑马程序员</author>
<year>2015</year>
<kinds>IT</kinds>
</book>
<book id="b2">
<name>软件工程</name>
<author>吴磊</author>
<year>2012</year>
<kinds>IT</kinds>
</book>
<book id="b3">
<name>经济学原理</name>
<author>曼昆</author>
<year>2011</year>
<kinds>经济学</kinds>
</book>
<book id="b4">
<name>编译原理</name>
<author>王一宾</author>
<year>2006</year>
<kinds>IT</kinds>
</book>
</bookstore>
结果为: