[学习笔记]XML解析之DOM4J
2015-07-23 23:29
501 查看
DOM4J
XML解析
1.常用API
解析器:SAXReader文档对象:Document
元素对象:Element
文档帮助类(用于创建节点):DocumentHelper
文档对象子类:DefaultElement
文档对象子类:BaseElement
格式化输出对象:OutputFormat
保存文件对象:XMLWriter
2.解析XML获取文档对象
publicstaticvoidmain(String[]args){//创建SAXReader对象SAXReaderreader=newSAXReader();//解析XML获取Document对象try{Documentdoc=reader.read("/bin/LocalList.xml");}catch(DocumentExceptione){e.printStackTrace();}}
3.获取节点文本内容
privatestaticStringgetElementText(Documentdoc){//获取根节点Elementroot=doc.getRootElement();//获取指定节点集合List<Element>elements=root.elements("City");//获取指定节点Elemente=elements.get(7);//获取指定节点的文本内容Stringtext=e.getText();returntext;}
4.递归获取所有节点的文本
privatestaticvoidgetAllElementText(Documentdoc){
//获取根节点
Elementroot=doc.getRootElement();
//递归遍历所有节点
recursion(root);
}
//使用深度优先搜索递归遍历所有节点
privatestaticvoidrecursion(Elementnode){
//如果非元素节点,则直接返回
if(node.getNodeType()!=Element.ELEMENT_NODE){
return;
}
//如果该节点无子元素节点,则输出元素文本
if(node.elements().isEmpty()){
System.out.println(node.getText());
}else{
//如果该节点有子元素,则递归遍历
List<Element>elements=node.elements();
for(Elementelement:elements){
//递归调用
recursion(element);
}
}
}
5.使用迭代器获取所有City节点的元素内容
privatestaticvoidgetCityElementText(Documentdoc){
//获取根元素节点
Elementroot=doc.getRootElement();
//使用元素迭代器进行迭代
for(Iterator<Element>iterator=root.elementIterator();iterator.hasNext();){
Elemente=iterator.next();
//如果该节点无子元素节点,则输出元素文本内容
if(e.elements().isEmpty()){
System.out.println(e.getText());
}
}
}
6.将Document保存到XML中
privatestaticvoidsaveXML(Documentdoc){
try{
//创建XML文件的字节输出流
OutputStreamout=newFileOutputStream("src/LocalList.xml");
//获取数据格式的对象,createCompactFormat紧凑格式,createPrettyPrint缩进格式
OutputFormatformat=OutputFormat.createPrettyPrint();
//创建XMLWriter对象
XMLWriterwriter=newXMLWriter(out,format);
//将DOM树写入XML文件
writer.write(doc);
//关闭资源
writer.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
7.修改元素文本内容
privatestaticvoidupdate(Documentdoc){
//获取要修改节点
Elementroot=doc.getRootElement();
Elementelement=(Element)root.elements().get(3);
//修改文本内容
element.setText("天上人间");
//保存文件
saveXML(doc);
}
8.添加子元素节点
privatestaticvoidaddChild(Documentdoc){
//获取要添加的父元素节点
Elementroot=doc.getRootElement();
Elementcity=(Element)root.elements().get(3);
//创建要添加的子元素节点
Elementstreet=DocumentHelper.createElement("street");
//ElementstreetE1=newDefaultElement("street");
//ElementstreetE2=newBaseElement("street");
//设置节点的文本内容
street.setText("南天门大街");
//将子节点添加到父节点中
city.add(street);
//保存文件
saveXML(doc);
}
9.添加兄弟元素节点
publicstaticvoidaddSibling(Documentdoc){
//获取目标元素节点
Elementroot=doc.getRootElement();
List<Element>elist=root.elements("City");
//创建要添加的元素节点
Elementcity=newDefaultElement("City");//<City></City>
//设置新节点的文本
city.setText("哈哈区");
//在指定位置加入元素city
elist.add(4,city);
//保存文件
saveXML(doc);
}
10.删除指定节点
publicstaticvoidremoveElement(Documentdoc){
//获取要删除节点
Elementroot=doc.getRootElement();
Elementcity=(Element)root.elements("City").get(3);
Elementstreet=(Element)city.elements("street").get(0);
//用父节点删除子节点
city.remove(street);
//保存文件
saveXML(doc);
}
11.为节点添加属性
publicstaticvoidaddAttribute(Documentdoc){
//获取要添加属性的节点
Elementroot=doc.getRootElement();
Elementcity=(Element)root.elements("City").get(3);
//为节点添加属性
city.addAttribute("type","food");
//保存文件
saveXML(doc);
}
XPath
概述
XPath的作用就像在一个文件系统中定位文件一样在XML文件中定位元素,XPath是由W3C的XPath1.0标准所描述。
标准
1.如果路径以斜线/开始,那么该路径就表示到一个元素的绝对路径。
/AAA/CCC:选择AAA的所有CCC子元素。
2.如果路径以双斜线//开头,则表示选择文档中所有满足双斜线//之后规则的元素(无论层级关系)。
//DDD/BBB:选择父元素是DDD的所有BBB元素。
3.星号*表示选择所有由星号之前的路径所定位的元素。
/*/*/*/BBB:选择所有的有3个祖先元素的BBB元素。//*:选择所有元素。
4.方块号里的表达式可以进一步的指定元素,其中数字表示元素在选择集里的位置,而last()函数则表示选择集中的最后一个元素。
/AAA/BBB[1]:选择AAA的第一个BBB子元素。/AAA/BBB[last()]:选择AAA的最后一个BBB子元素。
5.使用@符号来选择特定的属性或特定属性的元素。
//@id:选择所有的id属性。//BBB[@id]:选择有id属性的BBB元素。
//BBB[not(@*)]:选择没有属性的BBB元素。
6.属性的值可以被用来作为选择的准则,normalize-space函数删除了前部和尾部的空格,并且把连续的空格串替换为一个单一的空格。
//BBB[@id='b1']:选择含有属性id且其值为'b1'的BBB元素。//BBB[normalize-space(@name)='bbb']:选择含有属性name且其值(在用normalize-space函数去掉前后空格后)为'bbb'的BBB元素。
7.多个路径可以用分隔符|合并在一起。
/AAA/EEE|//BBB:选择所有的BBB元素和作为AAA子元素的所有EEE元素。
8.相关函数
count():计数所选元素的个数。name():返回元素的名称。
start-with():在该函数的第一个参数字符串是以第二个参数字符开始的情况返回true。
contains():当其第一个字符串参数包含有第二个字符串参数时返回true。
string-length:返回字符串的字符数,应用<替代<,用>代替>。
//*[count(BBB)=2]:选择含有2个BBB子元素的元素。
//*[name()='BBB']:选择所有名称为BBB的元素,等价于//BBB。
//*[starts-with(name(),'B')]:选择所有名称以"B"起始的元素。
//*[contains(name(),'C')]:选择所有名称包含"C"的元素。
//*[string-length(name())<3]:选择名字长度小于3的元素。
DOM4J中XPath的使用
1.使用XPath获取指定节点
privatestaticvoidgetNode(Documentdoc){
Nodenode=doc.selectSingleNode("/State/City/street");
System.out.println(node.getText());
}
2.使用XPath获取节点集合
privatestaticvoidgetNodes(Documentdoc){
List<Node>nodes=doc.selectNodes("/State/City");
System.out.println(nodes.size());
}
3.使用XPath获取指定属性
privatestaticvoidgetAttribute(Documentdoc){
//获取拥有Name属性的节点
Nodenode=doc.selectSingleNode("//*[@Name]");
//获取该节点的Name属性值
Stringname=node.valueOf("@Name");
System.out.println(name);
}
案例
学生信息存储Dom4jUtils:DOM4J解析的工具类,包括获取文档对象方法和保存文件方法。
publicclassDom4jUtils{
/**
*获取XML数据的Document对象
*
*@return
*/
publicstaticDocumentgetDocument(Stringpath){
if(path==null){
returnnull;
}
//创建XML解析器
Documentdoc=null;
SAXReaderreader=newSAXReader();
try{
//解析XML文件
doc=reader.read(path);
}catch(DocumentExceptione){
//异常处理
System.out.println("读取XML失败!");
e.printStackTrace();
}
returndoc;
}
/**
*将Document对象保存到XML文件中
*
*@paramdoc要保存的Document对象
*@return
*/
publicstaticbooleansaveXml(Documentdoc,Stringpath){
if(path==null||doc==null){
returnfalse;
}
//创建保存格式
OutputFormatof=OutputFormat.createPrettyPrint();
//创建XML写入对象
XMLWriterwriter=null;
try{
//将Document对象写入到XML文件中
OutputStreamos=newFileOutputStream(newFile(path));
writer=newXMLWriter(os,of);
writer.write(doc);
}catch(IOExceptione){
//异常处理
System.out.println("文件写入错误!");
e.printStackTrace();
returnfalse;
}finally{
//资源释放
if(writer!=null){
try{
writer.close();
}catch(IOExceptione){
System.out.println("资源关闭错误!");
e.printStackTrace();
returnfalse;
}
}
}
returntrue;
}
}
config.xml:配置具体Dao的实现类名,xml数据存储路径。
<?xmlversion="1.0"encoding="UTF-8"?>
<dao>
<student>
<class>com.xml.dao.impl.StudentDaoByDom4j</class>
<db>src/com/xml/db/student.xml</db>
</student>
</dao>
student.xml:学生数据存储的xml文件。
<?xmlversion="1.0"encoding="UTF-8"?>
<students>
<studentstudentid="1255"classid="55">
<name>帅哥</name>
<gender>男</gender>
<score>90</score>
</student>
</students>
StudentDao:DAO的接口设计
packagecom.xml.dao;
importcom.xml.bean.Student;
publicinterfaceStudentDao{
/**
*添加学生信息
*@params要添加的学生对象
*@return
*/
publicbooleanadd(Students);
/**
*删除学生的信息
*@paramsid要删除的学生id
*@return
*/
publicbooleandelete(intsid);
/**
*查询学生成绩
*@paramsid要查询的学生id
*@return
*/
publicfloatgetScore(intsid);
}
StudentDaoFactory:DAO的获取工厂类,该类为枚举单例,通过config.xml的配置信息,提供获取具体DAO对象的公有方法。
packagecom.xml.dao;
importorg.dom4j.Document;
importcom.xml.util.Dom4jUtils;
publicenumStudentDaoFactory{
dao;
publicStudentDaogetInstance(){
StudentDaosdao=null;
//获取配置信息XML文档的Document对象
Documentdoc=Dom4jUtils.getDocument("bin/com/xml/config/config.xml");
//获取StudentDao的实现类名
StringclassName=doc.selectSingleNode("/dao/student/class").getText();
//创建StudentDao实现类
try{
sdao=(StudentDao)Class.forName(className).newInstance();
}catch(InstantiationException|IllegalAccessException|ClassNotFoundExceptione){
System.out.println("配置信息错误!找不到该类。");
e.printStackTrace();
}
returnsdao;
}
}
StudentDaoByDom4j:DAO的实现类,根据配置信息能够获取具体数据XML的位置,并对之操作。
packagecom.xml.dao.impl;
importorg.dom4j.Document;
importorg.dom4j.Element;
importorg.dom4j.Node;
importcom.xml.bean.Student;
importcom.xml.dao.StudentDao;
importcom.xml.util.Dom4jUtils;
publicclassStudentDaoByDom4jimplementsStudentDao{
privateDocumentdoc=null;
privateStringpath=null;
publicStudentDaoByDom4j(){
//获取配置信息XML文档的Document对象
Documentconfig=Dom4jUtils.getDocument("bin/com/xml/config/config.xml");
//获取学生信息存储路径
this.path=config.selectSingleNode("/dao/student/db").getText();
//获取学生信息XML文档的Document对象
this.doc=Dom4jUtils.getDocument(this.path);
}
@Override
publicbooleanadd(Students){
//性别预处理
String[]mask={"男","女","人妖"};
//在根节点下创建学生元素并设置属性
Elemente=doc.getRootElement().addElement("student")
.addAttribute("studentid",String.valueOf(s.getId()))
.addAttribute("classid",String.valueOf(s.getClassId()));
//为学生元素添加子元素
e.addElement("name").setText(s.getName());
e.addElement("gender").setText(mask[s.getGender()]);
e.addElement("score").setText(String.valueOf(s.getScore()));
//将Document保存到XML文件中
Dom4jUtils.saveXml(doc,this.path);
returntrue;
}
@Override
publicbooleandelete(intsid){
//获取要删除的节点
Nodenode=doc.selectSingleNode("/students/student[@studentid='"+String.valueOf(sid)+"']");
//使用父节点删除该节点
node.getParent().remove(node);
//将Document保存到XML文件中
Dom4jUtils.saveXml(doc,this.path);
returntrue;
}
@Override
publicfloatgetScore(intsid){
//获取要查询成绩的学生成绩
Stringscore=doc.selectSingleNode("/students/student[@studentid='"
+String.valueOf(sid)+"']/score").getText();
//返回成绩
returnFloat.parseFloat(score);
}
}
测试
packagecom.xml.test;
importorg.junit.Test;
importcom.xml.bean.Student;
importcom.xml.dao.StudentDao;
importcom.xml.dao.StudentDaoFactory;
publicclassStudentDaoTest{
privateStudentDaosdao=null;
{
sdao=StudentDaoFactory.dao.getInstance();
}
@Test
publicvoidtestAdd(){
Students=newStudent(1248,"苏苏",55,2,80);
sdao.add(s);
}
@Test
publicvoidtestDelete(){
sdao.delete(1248);
}
@Test
publicvoidtestGetScore(){
floatscore=sdao.getScore(1255);
System.out.println(score);
}
}
相关文章推荐
- jquery-mobile 学习笔记之一(基础属性)
- Axure的简单操作(倒计时基础版)
- jsfl脚本设置导出AS链接名遇到的奇怪问题
- Android中管理多个Fragment的最佳实践,完美解决保存状态与重影问题
- poj 1190 生日蛋糕(剪枝+深搜)
- QT打包发布NSIS
- C# 通过后台获取浏览器域名
- [学习笔记]XML解析之JAXP
- 大意带来的教训----误把C盘下面用户文件夹删除
- event delivly 事件分发, 响应链
- Axure的简单操作(模糊搜索)
- define和typedef 区别
- Chrome中的Device模块调式响应性设计
- Fatal error: require() [function.require]: Failed opening required 'db.php'
- linux 设置系统时间和硬件RTC时间
- 杭电ACM2094——产生冠军~~拓扑排序
- Struts2获取ServletApi对象的4种方法
- 在ScrollView中嵌套ListView
- IBM Worklight 移动应用程序开发的八个步骤
- Provisioning Services and CIFS Shares