使用dom4j解析xml的前提准备:
DOM4j解析原理:xml解析器一次性把整个xml文档加载进内存,然后在内存中构建一颗Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到xml文档的内容。
1)导入dom4j的核心包。 dom4j-1.6.1.jar(此包为例子
2)编写Dom4j读取xml文件代码)
1.在项目的src目录下新建contact.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<contactList>
<contact id="001">
<name>张三</name>
<age>20</age>
<phone>13112345678</phone>
<qq>123456789</qq>
<contact id="002">
<name>李四</name>
<age>21</age>
<phone>12398765432</phone>
<qq>987654321</qq>
</contact>
</contactList>
- 第一步,dom4j读取文档的例子
public class Demo1{
public static void main(String[] args) throws DocumentException{
//1.创建xml文档解析器
SAXReader saxReader = new SAXReader();
//2.文档读取
Document doc = saxReader.read(new File("./src/contact.xml"));
System.out.println(doc);
}
}
输出结果为:
org.dom4j.tree.DefaultDocument@2e46638f [Document: name file:///E:/StudyWork/day04/./src/contact.xml]
说明解析器的流对象已经读到此xml文件
- 第二步,使用dom4j读取文件内容
@Test
public void test01() throws DocumentException{
//1.创建一个xml解析器对象
SAXReader saxReader = new SAXReader();
//2.读取xml文档
Document doc = saxReader.read(new File("./src/contact.xml"));
//3.得到当前节点下所有的子节点对象(doc下的第一层标签,只到第一层)
Iterator<Node> iter = doc.nodeIterator();
while(iter.hasNext()){
Node node = iter.next();
String name = node.getName();
System.out.println("第一层节点的名称为:"+name);
//继续取出下面节点名称,首先要明白只有标签节点才有子节点
//先判断是否为标签节点
if(node instanceof Element){
Element elem = (Element) node;
//取出当前标签节点下所有的节点名称
Iterator<Node> it = elem.nodeIterator();
while(it.hasNext()){
Node elemNode = it.next();
String elemName = elemNode.getName();
System.out.println("第二层节点的名称为:"+elemName);
}
}
}
}
输出结果:
第一层节点的名称为:contactList
第二层节点的名称为:null
第二层节点的名称为:contact
第二层节点的名称为:null
第二层节点的名称为:contact
第二层节点的名称为:null
为什么会有输出为null的呢?我们继续往下解析:
@Test
public void test02() throws DocumentException{
//1.创建xml解析器
SAXReader saxReader = new SAXReader();
//2.读取xml文档
Document doc = saxReader.read(new File("./src/contact.xml"));
//getRootElement() 得到根标签)<contactList>
Element rootElem = doc.getRootElement();
getChildNodes(rootElem);
}
/**
* 此方法用于获取传入的标签下的所有子节点
* @param elem
*/
private void getChildNodes(Element elem){
System.out.println(elem.getName());
//根据父级节点获取子节点
Iterator<Node> iterator = elem.nodeIterator();
while(iterator.hasNext()){
Node node = iterator.next();
//看该子节点下是否还有子孙节点,但只有标签节点才有
if(node instanceof Element){
Element element = (Element) node;
//递归
getChildNodes(element);
}
}
}
输出结果:
contactList
contact
name
age
phone
qq
contact
name
age
phone
qq
- 获取xml的标签
/**
* 获取标签
* @throws DocumentException
*/
@Test
public void test03() throws DocumentException{
//1.读取xml文档 返回Document对象
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(new File("./src/contact.xml"));
//2.得到根标签
Element rootElem = doc.getRootElement();
String name = rootElem.getName();
System.out.println("根标签名称为:"+name);
//3.得到当前标签下第一个指定名称的自标签
Element contactElem = rootElem.element("contact");
System.out.println("第一个指定名称的子标签为:"+contactElem.getName());
输出结果为:根标签名称为:contactList
第一个指定名称的子标签为:contact
//4.得到当前标签下所有指定名称的子标签
Iterator<Element> elementIterator = rootElem.elementIterator("contact");
while(elementIterator.hasNext()){
Element elem = elementIterator.next();
System.out.println("当前标签下所有指定名称的子标签"+elem.getName());
}
输出结果为:根标签名称为:contactList
当前标签下所有指定名称的子标签contact
当前标签下所有指定名称的子标签contact
//5.得到当前标签下的所有子标签
List<Element> list = rootElem.elements();
//遍历
for(Element e:list){
System.out.println(e.getName());
}
输出结果为:根标签名称为:contactList
contact
contact
//6.获取更深层次的标签(方法只能一层层获取)
Element element = doc.getRootElement().element("contact").element("name");
System.out.println(element.getName());
输出结果为:根标签名称为:contactList
name
}
- 获取标签的属性
@Test
public void test04() throws DocumentException{
//1.读取xml文档,返回Document对象
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(new File("./src/contact.xml"));
//获取属性:(先获得属性所在的标签对象,然后才能获得属性)
//1.得到标签对象
Element contactElem = doc.getRootElement().element("contact");
//2.得到属性
//2.1得到指定名称的属性
String idValue = contactElem.attributeValue("id");
System.out.println(“id的属性值为:”+idValue);
输出结果:id的属性值为:001
//2.2得到指定属性名称的属性对象
Attribute idAttr = contactElem.attribute("id");
//getName 属性名 getValue 属性值
System.out.println(idAttr.getName()+"="+idAttr.getValue());
输出结果:id=001
//2.3得到所有属性对象,返回List集合
List<Attribute> attrList = contactElem.attributes();
for(Attribute attr:attrList){
System.out.println(attr.getName()+"="+attr.getValue());
}
输出结果:id=001
//2.4得到所有属性对象,返回迭代器的
Iterator<Attribute> it = contactElem.attributeIterator();
while(it.hasNext()){
Attribute attr = it.next();
System.out.println(attr.getName()+"="+attr.getValue());
}
输出结果:id=001
需要返回迭代器时用此方法
}
- 获取xml的文本内容:
/**
* 读取xml的文本内容
* @throws DocumentException
*/
@Test
public void test05() throws DocumentException{
//1.读取xml文档,返回Document对象
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(new File("./src/contact.xml"));
/**
* 注意空格和换行也是xml的内容
*/
String content = doc.getRootElement().getText();
System.out.println(content);
输出结果为:空行
//获取文本(先获取标签,再获取标签上的文本)
Element nameElem = doc.getRootElement().element("contact").element("name");
//1.得到文本
String text = nameElem.getText();
System.out.println(text);
输出结果为:张三
//2.得到指定子标签的文本内容
String text2 = doc.getRootElement().element("contact").elementText("phone");
System.out.println(text2);
输出结果为:13142199455
}
- 到此,我们已经掌握了xml中队标签、属性、文本的操作,其实都是基于DOM树的原理,下面我们解析整个xml,并将其原有格式,打印到控制台。
public class Demo3 {
@Test
public void test() throws DocumentException{
//1.创建文件解析器,读取xml文档内容
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("./src/contact.xml");
//读取根标签
Element rootElem = doc.getRootElement();
//拼接格式
StringBuffer sb = new StringBuffer();
getChildNodes(rootElem, sb);
System.out.println(sb.toString());
}
private void getChildNodes(Element elem,StringBuffer sb){
//开始标签,先拼头部
sb.append("<"+elem.getName());
//拼接头部的属性,第一次在根标签下属性为空
List<Attribute> attrs = elem.attributes();
if(attrs!=null){
for(Attribute attr:attrs){
sb.append(" "+attr.getName()+"=\""+attr.getValue()+"\"");
}
}
//头部拼接完成
sb.append(">");
//获取文本内容
Iterator<Node> it = elem.nodeIterator();
while(it.hasNext()){
Node node = it.next();
//标签
if(node instanceof Element){
Element el = (Element) node;
getChildNodes(el, sb);
}
//文本
if(node instanceof Text){
Text text = (Text) node;
sb.append(text.getText());
}
}
//结束标签
sb.append("</"+elem.getName()+">");
}
}
输出结果为:
<?xml version="1.0" encoding="utf-8"?>
<contactList>
<contact id="001">
<name>张三</name>
<age>20</age>
<phone>13142199455</phone>
<qq>123456789</qq>
</contact>
<contact id="002">
<name>李四</name>
<age>21</age>
<phone>15975221505</phone>
<qq>987654321</qq>
</contact>
</contactList>