dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面还可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,所以可以知道dom4j无论在哪个方面都是非常出色的。如今可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这已经是必须使用的jar包, 很多框架项目也用它来读写配置文件。
解析XML文档
读写XML文档主要依赖于org.dom4j.io包,其中提供DOMReader和SAXReader两类不同方式,而调用方式是一样的。这就是依靠接口的好处。
SAXReader sax=new SAXReader();
// 学习一下服务器下的资源路径加载方式(因为我们的资源已经从MyEclipse中发布到Tomcat服务器中了,所以跟原来纯Java项目不一样了)
// 利用当前类找到它的类加载器,然后通过该类加载器再去获得资源路径
path = Dom4jFactory.class.getClassLoader().getResource("photos.xml").getPath();
dom = sax.read(new FileInputStream(path));
Document dom=sax.read("./xml4/users.xml");
其中,reader的read方法是重载的,可以从InputStream, File, Url等多种不同的源来读取。得到的Document对象就代表了整个XML。
- 遍历XML树
SAXReader sax=new SAXReader();
Document dom=sax.read("./xml4/users.xml");
Element root=dom.getRootElement();//获得根节点
Iterator<Element> it=root.elementIterator();
while(it.hasNext()){
Element e=it.next();
String id=e.attributeValue("id");
String name=e.elementText("name");
String age=e.elementText("age");
System.out.println("id:"+id+",name:"+name+",age:"+age);
}
- 添加一个元素
SAXReader sax=new SAXReader();
Document dom=sax.read("./xml4/users.xml");
Element root=dom.getRootElement();//获得根节点
Element eUser=root.addElement("user");
eUser.addAttribute("id", "D001");
Element eName=eUser.addElement("name");
eName.addText("王建安");
Element eAge=eUser.addElement("age");
eName.addText("25");
- 删除最后一个元素
SAXReader sax=new SAXReader();
Document dom=sax.read("./xml4/users.xml");
Element root=dom.getRootElement();//获得根节点
List<Element> list=root.elements();
Element e=list.get(list.size()-1);
e.getParent().remove(e);
FileWriter fw=new FileWriter("./xml4/users.xml");
dom.write(fw);
fw.flush();
fw.close();
- 文件的输出与保存
//法1---功能有限
FileWriter fw = new FileWriter("./xml4/users.xml");
dom.write(fw);
fw.close();
//法2---功能更强,能设置编码之类的格式
FileWriter fw = new FileWriter("./xml4/users.xml");
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter xw=new XMLWriter(fw,fromat);
xw.write(dom);
xw.close();
- 创建一个xml文档
一般创建XML是写文件前的工作,这就像StringBuffer一样容易。
Document dom=DocumentHelper.createDocument();
Element root=dom.addElement("hncu");
root.addElement("department").addAttribute("id", "dep").addElement("xky").setText("信科院");
root.addElement("person").addElement("student").addAttribute("name", "stud");
XMLWriter xw=new XMLWriter(new FileOutputStream("./xml4/contact.xml"));
xw.write(dom);
xw.close();
xpath
XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言。XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。起初 XPath 的提出的初衷是将其作为一个通用的、介于XPointer与XSLT间的语法模型。但是 XPath 很快的被开发者采用来当作小型查询语言
- 下面我来演示一些简单的语法:
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
SAXReader sax=new SAXReader();
Document dom=sax.read("./xml4/contact.xml");
Element root=dom.getRootElement();//获得根节点
//String xpath="//contact";//表示所有的contact子孙节点
//String xpath="/*/user";//第一个"/"表示当前元素
String xpath="//aaa/preceding::*";//选择<aaa>前面的所有元素
//String xpath="//user[@name][@pwd]";//选择同时包含name和pwd属性的user元素
//String xpath="//user[@name='Jack'][@pwd='1234']";//选择name='Jack'且pwd='1234'那个user元素
//String xpath="//user[@name='"+name+"'][@pwd='"+pwd+"']";//选择name='Jack'且pwd='1234'那个user元素
String xpath="//user[fn:lower-case(@name)='"+name+"'][fn:lower-case(@pwd)='"+pwd+"']";//选择name='Jack'且pwd='1234'那个user元素
List<Element> list=root.selectNodes(xpath);//
for(int i=0;i<list.size();i++){
Element e=list.get(i);
System.out.println(e.getName()+","+e.attributeValue("id"));
}
XPath函数
函数定义
函数名
返回类型(不能用void)
参数类型常用函数
节点集函数
last() 返回当前上下文中的最后一个节点的位置号数。
position() 返回当前节点的位置的数字,位于第多少个。
count(node-set) 返回节点集node-set中的节点数。
id(mark) 根据在DTD中声明为ID类型的标识符选择元素,返回一个节点集。
name() 返回节点名称。
local-name() 返回不带名称空间的节点名称。
namespace-uri() 返回名称空间。字符串函数
string(object) 把节点集、数字、布尔值等转化成字串并返回。
format-number(num) 把数字转化成字串并返回。
concat(string1,string2…) 合并多个字串并返回。
starts-with(string1,string2) 如果字串string1开头带string2的所有字符则返回true,否则返回false。
contains(string1,string2) 如果字串string1包含string2的所有字符则返回true,否则返回false。
substring(string,number1,number2) 取string中从位置number1开始,number2长的子串,number2可省略。
substring-before(string1,string2) 取string1在string2第一次出现位置之前的子串。
substring-after(string,string) 取string1在string2第一次出现位置之后的子串。
string-length(string) 返回string的长度数字。
normalize-space(string) 清除string头尾的空白字符并且把连续的空白字符替换为一个再返回。
translate(string1,string2,string3) 假如string1中的字符在string2中有出现,那么替换为string3对应string2的同一位置的字符,假如string3这个位置取不到字符则删除string1的该字符。布尔函数
boolean(object) 非0和NaN的数字/非空节点/长度大于0的字串返回true,非基本类型的转换有时无法估计。
not(boolean) 对布尔值取反。
true() 返回true。
false() 返回false。
lang(string) 如果上下文节点的lang属性和string相同则返回true。数字函数
number(object) 使对象转化成数字,布尔值true为1,false为0;节点集首先转换成字符串,字符串转换成数字或者NaN。
sum(node-set) 对节点集node-set中的所有节点应用number()函数后返回和。
floor(number) 返回不大于数字number的最大整数。
ceiling(number) 返回不小于数字number的最小整数。
round(number) 返回和数字number的四舍五入结果。Xpath处理带有命名空间的XML文档
- 有关文档