上面我们已经学习了DOM和SAX两种解析XML的方式,但是总体来说,感觉这两种方式还是不太方便,解析起来非常费劲,非常繁琐,不是特别令人满意。所以现在在开源的世界里面,很多人或是很多社区已经帮助我们实现出来了针对XML解析的这些库,我们可以直接拿来用。经历过上面的DOM和SAX那么繁琐的解析方式之后,下面要讲的这些解析方式使用起来非常简单,非常方便。学习起来比较简单,经历过痛苦之后尝到甜头了。下面讲的这些解析方式在实际开发里面用的非常多,实际开发里面其实很少有人直接用JAXP(DOM或SAX)这种解析方式,但是它是基础,必须会。
下面要讲解的实际开发中常用的使用起来非常简单的解析方式有
JDOM和
DOM4J两种:
首先讲解JDOM:
JDOM(http://www.jdom.org/)。
附件xml_6.pdf包含JDOM详细笔记,是上课课件。仔细阅读
附件jdom-1.1.1.zip,它里面包含了jdom相关的所有内容,是从官网下载的完整包(里面包含API文档),网盘下载地址
:http://pan.baidu.com/s/1b44OH
JDOM将DOM和SAX结合起来了,并且弥补了它们各自的不足之处,并且专门为java服务的,使用起来非常简单,详细笔记查看附件xml_6.pdf。
JDOM的使用是直截了当的,非常爽。
JDOM是由以下几个包组成的:
---org.jdom包含了所有的xml文档要素的java类
---org.jdom.adapters包含了与dom适配的java类
---org.jdom.filter包含了xml文档的过滤器类
---org.jdom.input包含了读取xml文档的类
---org.jdom.output包含了写入xml文档的类
---org.jdom.transform包含了将jdomxml文档接口转换为其他xml文档接口
---org.jdom.xpath包含了对xml文档xpath操作的类。
Org.jdom这个包里的类是你解析xml文件后所要用到的所有数据类型:
---Attribute
---CDATA
---Coment
---DocType
---Document
---Element
---EntityRef
---Namespace
---ProscessingInstruction
---Text
使用jdom需要引入jdom.jar文件,这个文件在附件的jdom-1.1.1.zip包里面。
下面是使用JDOM解析XML的一些示例:
JDomTest1.java:
package com.shengsiyuan.xml.jdom;
import java.io.FileOutputStream;
import org.jdom.Attribute;
import org.jdom.Comment;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
/**
* JDOM的第一个使用示例
* 使用JDOM将一个内存里面构造好的XML文件写到硬盘上
* 类: JDomTest1 <br>
* 描述: TODO <br>
* 作者:
* 时间: Dec 10, 2013 4:38:50 PM
*/
public class JDomTest1 {
public static void main(String[] args) throws Exception {
// 文档
Document document = new Document();
// 元素
Element root = new Element("root");
// 将元素添加到文档里面
document.addContent(root);
// 注释
Comment comment = new Comment("This is my comments");
root.addContent(comment);
Element e = new Element("hello");
// 设置属性
e.setAttribute("souhu", "www.souhu.com");
root.addContent(e);
Element e2 = new Element("world");
// 属性
Attribute attr = new Attribute("test", "hehe");
e2.setAttribute(attr);
e.addContent(e2);
// 方法链编程风格
e2.addContent(new Element("aaa").setAttribute("a", "b").setAttribute(
"x", "y").setAttribute("gg", "hh").setText("text conent"));
// 定义XML的输出格式类,并在下面将此对象传递到XML的输出类XMLOutputter的对象里面去
// getPrettyFormat()是我们常见的比较好看的XML显示格式。
Format format = Format.getPrettyFormat();
// 设置缩进(演示此方法的使用,实际开发中上面的getPrettyFormat()方法获得的输出样式格式就很好看了)
format.setIndent(" ");
format.setEncoding("UTF-8");
// 实例化XML的输出类
XMLOutputter out = new XMLOutputter(format);
out.output(document, new FileOutputStream("jdom.xml"));
}
}
JDomTest2.java:
package com.shengsiyuan.xml.jdom;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
/**
* 将JDomTest1.java创建好的XML文档进行修改,修改之后将内容存放到另一个XML文件jdom2.xml
* 类: JDomTest2 <br>
* 描述: TODO <br>
* 作者:
* 时间: Dec 11, 2013 9:52:35 AM
*/
public class JDomTest2 {
public static void main(String[] args) throws Exception {
SAXBuilder builder = new SAXBuilder();
// 加载文档到内存里面,并返回文档对象
Document doc = builder.build(new File("jdom.xml"));
// 获得文档根元素
Element elemtent = doc.getRootElement();
System.out.println(elemtent.getName());
Element hello = elemtent.getChild("hello");
System.out.println(hello.getText());
// 获得所有属性
List list = hello.getAttributes();
for (int i = 0; i < list.size(); i++) {
Attribute attr = (Attribute) list.get(i);
String attrName = attr.getName();
String attrValue = attr.getValue();
System.out.println(attrName + "=" + attrValue);
}
// 删除hello元素里面的world子元素(包括world里面的所有东西也都删除了)
hello.removeChild("world");
XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
// 将修改过的XML文件写到新的文件里面去
out.output(doc, new FileOutputStream("jdom2.xml"));
}
}
附属类:
jdom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!--This is my comments-->
<hello souhu="www.souhu.com">
<world test="hehe">
<aaa a="b" x="y" gg="hh">text conent</aaa>
</world>
</hello>
</root>
jdom2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!--This is my comments-->
<hello souhu="www.souhu.com" />
</root>
JDOM的输出类(将构建好的XML输出到硬盘或是其它地方):XMLOutputter
JDOM的加载XML类(加载XML文档类):SAXBuilder、DOMBuilser、ResultSetBuilder
===========================上面讲解的是JDOM==========================
===========================下面讲解DOM4J=============================
下面讲解DOM4J:
Dom4J(www.dom4j.org)
这也是java里面用的非常多的另外一个解析XML框架。
DOM4J的来源:最开始是有JDOM,后来JDOM开发人员有一帮人就不在那干了,辞职了,自己搞出来一个DOM4J,既然这些人在JDOM干过,难免会留下JDOM的一些痕迹,因此DOM4J的使用方式以及API与JDOM很相似。
附件dom4j-1.6.1.zip,它里面包含了dom4j相关的所有内容,是从官网下载的完整包,网盘下载地址:http://pan.baidu.com/s/1vNo7O
要想使用dom4j,需要将dom4j-1.6.1.jar加入到classpath下面。
附件dom4j.chm,dom4jAPI文档,网盘下载地址:
http://pan.baidu.com/s/1nFJx0
DocumentHelper是使用Dom4J过程中一些辅助方法的集合,用于帮助做一些辅助的事情,相当于util包里面的内容一样。这个类里面的所有方法都是静态方法。
Dom4J里面通过XMLWriter将文档内容写到目的地里面去
下面是利用Dom4J创建、解析XML的一些使用示例:
Dom4JTest1.java:
package com.shengsiyuan.xml.dom4j;
import java.io.FileOutputStream;
import java.io.FileWriter;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
/**
* 使用Dom4J创建XML文档实例
* 类: Dom4jTest1 <br>
* 描述: TODO <br>
* 作者:
* 时间: Dec 11, 2013 11:03:22 AM
*/
public class Dom4JTest1 {
public static void main(String[] args) throws Exception {
// 创建一个文档并设置文档的根元素:第一种方式:
// Document document = DocumentHelper.createDocument();
// Element root = DocumentHelper.createElement("student");
// document.setRootElement(root);
// 创建一个文档并设置文档的根元素:第二种方式:
Element root = DocumentHelper.createElement("student");
Document document = DocumentHelper.createDocument(root);
root.addAttribute("name", "zhangsan");
// 在根元素下面添加子元素并且将新添加的元素返回
Element helloElement = root.addElement("hello");
Element worldElement = root.addElement("world");
helloElement.setText("hello");
worldElement.setText("world");
helloElement.addAttribute("age", "20");
// 将构建好的xml文档写到目的地
XMLWriter xmlWriter = new XMLWriter();
// 输出到控制台上
xmlWriter.write(document);
// 格式化输入的代码
OutputFormat format = new OutputFormat(" ", true);
// 将代码输出到student2.xml里面(输出的第二种使用方式)
XMLWriter xmlWriter2 = new XMLWriter(new FileOutputStream(
"student2.xml"), format);
xmlWriter2.write(document);
// 将代码输出到student3.xml里面(输出的第三种使用方式)
XMLWriter xmlWriter3 = new XMLWriter(new FileWriter("student3.xml"),
format);
xmlWriter3.write(document);
// 使用FileWriter字符流构造出来的XMLWriter写完之后需要清空缓冲
xmlWriter3.flush();
}
}
package com.shengsiyuan.xml.dom4j;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.DOMReader;
import org.dom4j.io.SAXReader;
/**
* 使用Dom4J解析XML(student2.xml)
* 有两种解析方式:SAXReader和DOMReader,分别做演示
* 类: Dom4JTest2 <br>
* 描述: TODO <br>
* 作者:
* 时间: Dec 11, 2013 1:45:02 PM
*/
public class Dom4JTest2 {
public static void main(String[] args) throws Exception {
// 第一种解析方式:SAXReader
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(new File("student2.xml"));
Element root = doc.getRootElement();
System.out.println("root element: " + root.getName());
// 获得所有的子元素,不包括空白
List childList = root.elements();
System.out.println(childList.size());
// 获得名称为hello的子元素列表
List childList2 = root.elements("hello");
System.out.println(childList2.size());
// 返回以hello作为标签名的第一个元素(因为标签名称为hello的元素可能有多个)
Element first = root.element("hello");
// 打印此标签元素里面名称为age的属性的值
System.out.println(first.attributeValue("age"));
// 迭代根元素里面的所有子元素
for (Iterator iter = root.elementIterator(); iter.hasNext();) {
Element e = (Element) iter.next();
System.out.println(e.attributeValue("age"));
}
System.out.println("-----------------------------------------");
// 第二种解析方式:DOMReader
// 记得在刚开始我们用DOM或SAX(JAXP)解析XML的时候使用的是org.w3c.dom.Document,但是当时感觉这两种方式直接解析XML的话非常繁琐、非常费劲。这里我们是用Dom4J在解析,
// 而Dom4J里面也恰好有一个同名的类org.dom4j.Document,我们在这里解析的方式是将org.w3c.dom.Document对象转换成org.dom4j.Document然后再使用Dom4J进行解析。
// 首先下面三步是获得student2.xml文档的org.w3c.dom.Document对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
org.w3c.dom.Document document = db.parse(new File("student2.xml"));
DOMReader domReader = new DOMReader();
// 将JAXP的org.w3c.dom.Document转换为Dom4J的org.dom4j.Document
Document d = domReader.read(document);
Element rootElement = d.getRootElement();
System.out.println(rootElement.getName());
}
}
附属类:student2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<student name="zhangsan">
<hello age="20">hello</hello>
<world>world</world>
</student>
笔记:
1、对于JDOM的Format类的
getRawFormat()方法,通常用于XML数据的网络传输,因为这种格式会去掉所有不必要的空白,因此能够减少网络传输的数据量。