在使用Java解析XML文档之前,我们先来了解了解什么是XML。
XML即可扩展的标记语言,可以定义语义标记(标签),是元标记语言。XML不像超文本标记语言HTML,HTML只能使用规定的标记,对于XML,用户可以定义自己需要的标记。XML(eXtensible Markup Language)和HTML(Hyper Text Markup Language)师出同门,都是从SGML(Standard Generalized Markup Language)延伸而出的标记语言。
一、解析数据之前,先创建一个XML文档
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book isbn="223">
<title>三体</title>
<author>刘慈欣</author>
<price>59</price>
</book>
<book isbn="456">
<title>失控</title>
<author>KK</author>
<price>99</price>
</book>
<book isbn="789">
<title>冰与火</title>
<author>乔治马丁</author>
<price>129</price>
</book>
</books>
可以看到,XML的编写与HTML相比,用户可以自定义标签,当然,标签的自定义也需要符合面向对象编程中的逻辑思想。
二、DOM解析原理
DOM,Document Object Model,文档对象模型。DOM是html和xml文档的编程接口规范,和平台、语言是无关的。利用dom规范,能够实现dom 文档和xml之间的相互转换,遍历、操作相应dom文档的内容。
DOM规范的核心就是树模型。
此外,JDOM是Java和DOM的结合体。JDOM 致力于建立一个完整的基于 Java 平台的、通过 Java 代码来访问、操作并输出 XML 数据。JDOM是用Java语言读、写、操作XML的新API函数。
DOM解析的原理如下图所示。
三、利用Eclipse创建一个Java项目,创建一个与XML文档相对应的类Book.java,如下:
public class Book {
// 书版本号
private String isbn;
// 书标题
private String title;
// 书作者
private String author;
// 书价格
private int price;
public Book() {
}
/**
* 构造方法
*
* @param isbn
* 版本号
* @param title
* 标题
* @param author
* 作者
* @param price
* 价格
*/
public Book(String isbn, String title, String author, int price) {
super();
this.isbn = isbn;
this.title = title;
this.author = author;
this.price = price;
}
/**
* 获得书版本号
*
* @return 版本号
*/
public String getIsbn() {
return isbn;
}
/**
* 设置书版本号
*
* @param isbn
* 版本号
*/
public void setIsbn(String isbn) {
this.isbn = isbn;
}
/**
* 获得书标题名字
*
* @return 标题
*/
public String getTitle() {
return title;
}
/**
* 设置书标题名字
*
* @param title
* 标题名字
*/
public void setTitle(String title) {
this.title = title;
}
/**
* 获得书的作者名字
*
* @return 作者名字
*/
public String getAuthor() {
return author;
}
/**
* 设置书的作者名字
*
* @param author
* 作者名字
*/
public void setAuthor(String author) {
this.author = author;
}
/**
* 获得书的价格
*
* @return 价格
*/
public int getPrice() {
return price;
}
/**
* 设置书的价格
*
* @param price
* 价格
*/
public void setPrice(int price) {
this.price = price;
}
/**
* 重写Object继承下来的toString方法,用于将书的字段变成字符串对象
*/
@Override
public String toString() {
return "Book [isbn=" + isbn + ", title=" + title + ", author=" + author
+ ", price=" + price + "]";
}
}
四、将第一步中的book.xml放置在该项目的目录下,便于java中使用相对路径找到该文件
五、创建一个包含main(主方法)的主类,用于解析book.xml文档,为其创建一个readXML的静态方法,因为要在main方法中进行调用,具体代码如下:
public class RWTest {
public static void main(String[] args) {
readXML();
}
private static void readXML() {
// 1.获得解析器工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
// 2.通过工厂获得解析器
DocumentBuilder builder = factory.newDocumentBuilder();
// 3.指定要解析的xml文件
File file = new File("book.xml");
// 4.解析数据:file ----> doc(树形结构)
Document doc = builder.parse(file);
// 创建一个列表用来保存book信息
List<Book> list = new ArrayList<>();
/*
* 节点 Node 1 元素节点 Element 2 属性节点 Attr 3 文本节点 Text
*/
// 通过标签取该xml文件中所有的Book标签,返回一个链表
NodeList nodeList = doc.getElementsByTagName("book");
// 解析每一个book元素,并将解析的数据存放到Book对象中
for (int i = 0; i < nodeList.getLength(); i++) {
// 从nodeList中获得结点元素
Element eBook = (Element) nodeList.item(i);
Attr aIsbn = eBook.getAttributeNode("isbn");
String isbn = aIsbn.getValue();
Element eTitle = (Element) eBook.getElementsByTagName("title").item(0);
String title = eTitle.getTextContent();
String author = eBook.getElementsByTagName("author").item(0).getFirstChild().getNodeValue();
String strPrice = eBook.getElementsByTagName("price").item(0).getTextContent();
int price = Integer.parseInt(strPrice);
// 将解析的数据存储到Book对象
Book book = new Book(isbn, title, author, price);
// 将book对象存放到list列表中
list.add(book);
// System.out.println(eTitle.getTextContent());
}
// 输出list
for (Book b : list) {
System.out.println(b);
}
} 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();
}
}
}
六、运行效果截图:
七、利用Java语言创建XML文档
在第五步创建的RWTest.java类(主类)中,再添加一个静态方法writeXML,然后再main方法中之直接调用,查看其效果。
private static void writeXML() {
// 保存书的list列表
ArrayList<Book> list = new ArrayList<>();
// 添加两本书
list.add(new Book("111", "Java语言学习", "Oracle", 39));
list.add(new Book("222", "Android编程学习", "Google", 49));
// Object ------> XML
// 1.生成doc树形结构
// (1)创建文档解析器
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
// (2)通过工厂获得解析器对象
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
Element root = doc.createElement("books");
// (3)遍历对象列表,生成book子树
for (int i = 0; i < list.size(); i++) {
Element book = doc.createElement("book");
// 设置book的属性和子结点
/*// 设置book的isbn属性————————方法一
book.setAttribute("isbn", list.get(i).getIsbn());*/
// 设置book的isbn属性————————方法二
Attr attrIsbn = doc.createAttribute("isbn");
attrIsbn.setValue(list.get(i).getIsbn());
book.setAttributeNode(attrIsbn);
// 设置book的子元素结点:title——————方法一
// 创建title元素结点
Element title = doc.createElement("title");
title.setTextContent(list.get(i).getTitle());
// 设置book的子元素结点:author——————方法二
// 创建author元素结点
Element author = doc.createElement("author");
// 创建一个文本结点
Text text = doc.createTextNode(list.get(i).getAuthor());
author.appendChild(text);
// 设置book的子元素结点:price——————采用方法一添加
// 创建price元素结点
Element price = doc.createElement("price");
price.setTextContent(String.valueOf(list.get(i).getPrice()));
// 将子结点元素添加到book结点中
book.appendChild(title);
book.appendChild(author);
book.appendChild(price);
// book对象已经 成功转成了book子树
root.appendChild(book);
}
doc.appendChild(root);
// 2.将树形结构写入磁盘文件,并保存为xml文件
// (1)创建一个转换器对象
Transformer transformer = TransformerFactory.newInstance().newTransformer();
// (2)创建源对象(树形结构)
Source source = new DOMSource(doc);
// (3)创建目标对象(xml文件)
Result result = new StreamResult(new File("book2.xml"));
// (4)开始转换
transformer.transform(source, result);
// (5)转换成功
System.out.println("转换成功");
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
注意:创建XML的时候需要指定XML文档所在的磁盘文件位置,所以在代码中最好先直接以名字指明,这样只要刷新项目就可以看到新建好的XML文档(我这里显示的是book2.xml),如下图所示。
直接打开book2.xml可以看到根据代码生成好的内容,如下图所示。
后面还会继续将利用Sax解析和第三方包的方法来解析XML文档。
谢谢您的关注和阅读,文章不当之处还请您不吝赐教~~~