/** * @author 朱君鹏 * xml作用:以前发明被用来替代html,但是现在只是为了做软件的配置文件(用的最多),另外一个作用是作为一个小型的数据库 * xml语法:标签名以字母、数字、下划线组成,并且只能以字母或者下划线开头,标签名区分大小写 * xml属性:一个标签中可以有多个标签,但是可以有多个属性,但是属性名不能重复,并且属性值必须用单引号或者双引号包含,不使用引号是错误的写法 * xml文档声明:<?xml version="1.0" encoding="utf-8"?> 文档声明只要是为了解决中文乱码问题,尤其是使用记事本修改xml文档时一定要注意 * xml解析:解析的方式有两种,解析的含义是用程序去读取或者修改xml文件,解析分为两种方式:分别是DOM、SAX,这两种解析的原理是完全不 * 一样的,其中DOM解析的原理是:一次性将xml文档加载进内存形成Document树,通过Document得到节点对象,通过节点对象得到xml文档中的信息 * DOM原理之下有一些功能工具供程序员使用,最常用的是DOM4J,民间开源组织提供 * 操作分别包含下面的内容: * 遍历xml,遍历之前需要明白下面的内容 * 首先整个xml文件读进内存之后形成了一颗树,并且树的树根只有一个,通过getRootElement获取其根元素 * (代表xml文件中的标签体,也就是被开闭标签包含的文本内容)、Attribute(属性,通过它可以获得xml文件中的属性) * 这样就组成了一个xml文档在内存中的Document对象树,分别对应的包为org.dom4j.Node、org.dom4j.Attribute、org.dom4j.Text、 * org.dom4j.Element,通过Document对象树可以得到其中的节点,通过节点又可以获取其中的节点信息,节点包括:节点类型、节点名称 * */
package com.jpzhutech.dom4j;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
public class TestDom4J {
public static void main(String[] args) {
System.out.println(readDocument().getName()); //调用readDocument函数形成Document对象
System.out.println(getRoot(readDocument()).getName()); //得到Element元素的名字,本例中读出的是contactlist
System.out.println(getRoot(readDocument()).getText()); //从该测试中我们得到在xml文件中,实际上不能包含多余的空格
//空格在xml文件中算是其中的内容
//所以<age>20</age>和<age>20 </age>是截然不同的
//本例中读出一系列的看不见的空格
}
//函数功能:指定xml文件名,从而将其从硬盘中读进内存并将其解析为一个Document树
public static Document readDocument(){
//创建dom4j解析器对象
SAXReader reader = new SAXReader();
//获取Document对象
Document document = null;
try {
document = reader.read(new File("./src/contact.xml"));
} catch (DocumentException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e); //将异常封装为运行时异常,这样做有两个好处:
//1.首先调用者不用处理这个异常(非运行时异常才需要处理)
//2.封装好之后仍能得到正确的异常信息
}
return document;
}
//函数功能:获取DOM树的根元素
public static Element getRoot(Document document){
return document.getRootElement();
}
//功能:输出contactlist以及contactlist下的子标签,只包含子标签,不包含孙子等标签
@Test
public void test1(){
//创建dom4j解析器对象
SAXReader reader = new SAXReader();
//获取Document对象
Document document = null;
try {
document = reader.read(new File("./src/contact.xml"));
} catch (DocumentException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e); //将异常封装为运行时异常,这样做有两个好处:
//1.首先调用者不用处理这个异常(非运行时异常才需要处理)
//2.封装好之后仍能得到正确的异常信息
}
//得到当前节点下的所有子节点对象,不包括孙子等节点
Iterator<Node> it = document.nodeIterator(); //document下面的子节点只包含根节点
while(it.hasNext()){
Node node = it.next();
String name = node.getName();
System.out.println(name);
//继续取出下面的子节点,只有标签节点才有子节点
if(node instanceof Element){ //这里限制了元素一定是Element,如果不是Elment就不会进入这个语句块中
Element element = (Element)node;
Iterator<Node> it1 = element.nodeIterator(); //在这里Node是类型,但是类型Element属于Node的类型(节点类型)
//Iterator<Element> it1 = element.nodeIterator(); //为什么是错误的?
while(it1.hasNext()){
Node node1 = it1.next();
//Element node1 = it1.next(); //为什么这种情况是错误的?
System.out.println(node1.getName());
}
}
}
}
//输出根标签以及根标签下的各级标签
@Test
public void test2(){
//创建dom4j解析器对象
SAXReader reader = new SAXReader();
//获取Document对象
Document document = null;
try {
document = reader.read(new File("./src/contact.xml"));
} catch (DocumentException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e); //将异常封装为运行时异常,这样做有两个好处:
//1.首先调用者不用处理这个异常(非运行时异常才需要处理)
//2.封装好之后仍能得到正确的异常信息
}
getChildElement(document.getRootElement());
}
//递归的将每个标签节点输出
public void getChildElement(Element element){
System.out.println(element.getName());
//Iterator<Node> it = element.nodeIterator();
List<Attribute> attribute = element.attributes();
for(Attribute attr : attribute){
System.out.println(attr.getName()+"="+attr.getValue());
}
String content = element.getText();
System.out.println(content);
List<Element> list = element.elements();
/*while(it.hasNext()){ Node node = it.next(); if(node instanceof Element){ Element el = (Element)node; getChildElement(el); } }*/
for(Element li : list){
getChildElement(li);
}
}
}
http://www.jpzhutech.com