14XML解析
XML解析
XML解析
DOM4J
DOM4J是dom4j.org出品的一个开源XML解析包Dom4j是一个易用的、开源的库,用于XML,XPath和XSLT的解析及相关应用。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。与其他一些XML解析包的比较,DOM4J的性能上存在明显优势,在多项测试中名列前茅。DOM4J使用起来非常简单。只要你了解基本的XML-DOM模型,就能使用。
10.2 DOM4J的接口
DOM4J最大的特色是使用大量的接口,它的主要接口都在org.dom4j这个包里定义:
|
Attribute定义了XML的属性 |
|
|
Branch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为, |
|
|
CDATA 定义了XML CDATA 区域 |
|
|
CharacterData是一个标识借口,标识基于字符的节点。如CDATA,Comment, Text. |
|
|
Comment 定义了XML注释的行为 |
|
|
定义了XML文档 |
|
|
DocumentType 定义XML DOCTYPE声明 |
|
|
Element定义XML 元素 |
|
|
ElementHandler定义了 Element 对象的处理器 |
|
|
被 ElementHandler 使用,用于取得当前正在处理的路径层次信息 |
|
|
Entity定义 XML entity |
|
|
Node为所有的dom4j中XML节点定义了多态行为 |
|
|
NodeFilter 定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate) |
|
|
ProcessingInstruction 定义 XML 处理指令. |
|
|
Text 定义XML 文本节点. |
|
|
Visitor 用于实现Visitor模式. |
|
|
XPath 在分析一个字符串后会提供一个XPath 表达式 |
表 10.1
看名字大致就知道它们的涵义如何了。要想弄懂这套接口,关键的是要明白接口的继承关系,如下图所示,大部分接口都是由Node继承来的。
|
表 10.2
10.3 下载与安装
可以到http://sourceforge.net/projects/dom4j下载其最新版。dom4j1.5的完整版大约13M,是一个名为dom4j-1.5.zip的压缩包,解压后有一个dom4j-1.5.jar文件,这就是应用时需要引入的类包,另外还有一个jaxen-1.1-beta-4.jar文件,一般也需要引入,否则执行时可能抛java.lang.NoClassDefFoundError: org/jaxen/JaxenException异常,其他的包可以选择用之。
10.4 程序示例
10.4.1 读取并解析XML文档
读写XML文档主要依赖于org.dom4j.io包,其中提供DOMReader和SAXReader两类不同方式,而调用方式是一样的。这就是依靠接口的好处。
|
// 从文件读取XML,输入文件名,返回XML文档 public Document read(String fileName) throws MalformedURLException, DocumentException { SAXReader reader = new SAXReader(); Document document = reader.read(new File(fileName)); return document; } |
表10.3
其中,reader的read方法是重载的,可以从InputStream, File, Url等多种不同的源来读取。得到的Document对象就带表了整个XML。
10.4.2 取得Root节点
读取后的第二步,就是得到Root节点。熟悉XML的人都知道,一切XML分析都是从Root元素开始的。
|
public Element getR9ootElement(Document doc){ return doc.getRootElement(); } |
表10.4
10.4.3 遍历XML树
DOM4J提供至少3种遍历节点的方法:枚举(Iterator),递归,Visitor模式。通常我们使用枚举方式,详细见下例。
|
// 枚举所有子节点 Iterator i = root.elementIterator(); while(i.hasNext()) { Element element = (Element) i.next(); } i = root.elementIterator(foo); // 枚举名称为foo的节点 while(i.hasNext()) { Element foo = (Element) i.next(); } i = root.attributeIterator(); // 枚举属性 while(i.hasNext()) { Attribute attribute = (Attribute) i.next(); } |
表10.5
10.4.4 字符串与XML的转换
有时候经常要用到字符串转换为XML或反之,
|
// XML转字符串 Document document = ...; String text = document.asXML(); // 字符串转XML String text = “<person> <name>James</name> </person>”; Document document = DocumentHelper.parseText(text); |
表10.6
10.4.5 创建XML
一般创建XML是写文件前的工作,这就像StringBuffer一样容易。
|
public Document createDocument() { Document document = DocumentHelper.createDocument(); Element root = document.addElement(root); Element author1 = root.addElement(author) .addAttribute(name, James) .addAttribute(location, UK) .addText(James Strachan); Element author2 = root.addElement(author) .addAttribute(name, Bob) .addAttribute(location, US) .addText(Bob McWhirter); return document; } |
表10.7
10.4.6 文件输出
一个简单的输出方法是将一个Document或任何的Node通过write方法输出
|
FileWriter out = new FileWriter( foo.xml ); document.write(out); |
表10.8
10.5 用Dom4j解析XML及中文问题
本节主要讨论了用dom4j解析XML的基础问题,包括建立XML文档,添加、修改、删除节点,以及(美化)输出和中文问题
10.5.1 建立一个XML文档
|
/** * 建立一个XML文档,文档名由输入属性决定 * @param filename 需建立的文件名 * @return 返回操作结果, 0表失败, 1表成功 */ public int createXMLFile(String filename){ /** 返回操作结果, 0表失败, 1表成功 */ int returnValue = 0; /** 建立document对象 */ Document document = DocumentHelper.createDocument(); /** 建立XML文档的根books */ Element booksElement = document.addElement("books"); /** 加入一行注释 */ booksElement.addComment("This is a test for dom4j"); /** 加入第一个book节点 */ Element bookElement = booksElement.addElement("book"); /** 加入show属性内容 */ bookElement.addAttribute("show","yes"); /** 加入title节点 */ Element titleElement = bookElement.addElement("title"); /** 为title设置内容 */ titleElement.setText("Dom4j Tutorials"); /** 类似的完成后两个book */ bookElement = booksElement.addElement("book"); bookElement.addAttribute("show","yes"); titleElement = bookElement.addElement("title"); titleElement.setText("Lucene Studing"); bookElement = booksElement.addElement("book"); bookElement.addAttribute("show","no"); titleElement = bookElement.addElement("title"); titleElement.setText("Lucene in Action"); /** 加入owner节点 */ Element ownerElement = booksElement.addElement("owner"); ownerElement.setText("O'Reilly"); try{ /** 将document中的内容写入文件中 */ XMLWriter writer = new XMLWriter(new FileWriter(new File(filename))); writer.write(document); writer.close(); /** 执行成功,需返回1 */ returnValue = 1; }catch(Exception ex){ ex.printStackTrace(); } return returnValue; } |
例10.2
|
说明: Document document = DocumentHelper.createDocument(); 通过这句定义一个XML文档对象。 Element booksElement = document.addElement("books"); 通过这句定义一个XML元素,这里添加的是根节点。 |
Element有几个重要的方法:
- addComment:添加注释
- addAttribute:添加属性
- addElement:添加子元素
最后通过XMLWriter生成物理文件,默认生成的XML文件排版格式比较乱,可以通过OutputFormat类的createCompactFormat()方法或createPrettyPrint()方法格式化输出,默认采用createCompactFormat()方法,显示比较紧凑,这点将在后面详细谈到。
生成后的xml文件内容如下:
|
<?xml version="1.0" encoding="UTF-8"?> <books> <book show="yes"> <title>Dom4j Tutorials</title> </book> <book show="yes"> <title>Lucene Studing</title> </book> <book show="no"> <title>Lucene in Action</title> </book> <owner>O'Reilly</owner> </books> |
表10.9
10.5.2 修改XML文档
有三项修改任务,依次为:
a. 如果book节点中show属性的内容为yes,则修改成no
b. 把owner项内容改为Tshinghua,并添加date节点
c. 若title内容为Dom4j Tutorials,则删除该节点
|
/** * 修改XML文件中内容,并另存为一个新文件 * 重点掌握dom4j中如何添加节点,修改节点,删除节点 * @param filename 修改对象文件 * @param newfilename 修改后另存为该文件 * @return 返回操作结果, 0表失败, 1表成功 */ public int ModiXMLFile(String filename,String newfilename){ int returnValue = 0; try{ SAXReader saxReader = new SAXReader(); Document document = saxReader.read(new File(filename)); /** 修改内容之一: 如果book节点中show属性的内容为yes,则修改成no */ /** 先用xpath查找对象 */ List list = document.selectNodes("/books/book/@show" ); Iterator iter = list.iterator(); while(iter.hasNext()){ Attribute attribute = (Attribute)iter.next(); if(attribute.getValue().equals("yes")){ attribute.setValue("no"); } } /** * 修改内容之二: 把owner项内容改为Tshinghua * 并在owner节点中加入date节点,date节点的内容为2004-09-11,还为date节点 *添加一个属性type **/ list = document.selectNodes("/books/owner" ); iter = list.iterator(); if(iter.hasNext()){ Element ownerElement = (Element)iter.next(); ownerElement.setText("Tshinghua"); Element dateElement = ownerElement.addElement("date"); dateElement.setText("2004-09-11"); dateElement.addAttribute("type","Gregorian calendar"); } /** 修改内容之三: 若title内容为Dom4j Tutorials,则删除该节点 */ list = document.selectNodes("/books/book"); iter = list.iterator(); while(iter.hasNext()){ Element bookElement = (Element)iter.next(); Iterator iterator = bookElement.elementIterator("title"); while(iterator.hasNext()){ Element titleElement=(Element)iterator.next(); if(titleElement.getText().equals("Dom4j Tutorials")){ bookElement.remove(titleElement); } } } try{ /** 将document中的内容写入文件中 */ XMLWriter writer = new XMLWriter(new FileWriter(new File(newfilename))); writer.write(document); writer.close(); /** 执行成功,需返回1 */ returnValue = 1; }catch(Exception ex){ ex.printStackTrace(); } }catch(Exception ex){ ex.printStackTrace(); } return returnValue; } |
例10.3
|
说明: List list = document.selectNodes("/books/book/@show" ); list = document.selectNodes("/books/book"); 上述代码通过xpath查找到相应内容。 通过setValue()、setText()修改节点内容。 通过remove()删除节点或属性。 |
10.5.3 格式化输出和指定编码
默认的输出方式为紧凑方式,默认编码为UTF-8,但对于我们的应用而言,一般都要用到中文,并且希望显示时按自动缩进的方式的显示,这就需用到OutputFormat类。
|
/** * 格式化XML文档,并解决中文问题 * @param filename * @return 执行结果码 */ public int formatXMLFile(String filename){ int returnValue = 0; try{ SAXReader saxReader = new SAXReader(); Document document = saxReader.read(new File(filename)); XMLWriter writer = null; /** 格式化输出,类型IE浏览一样 */ OutputFormat format = OutputFormat.createPrettyPrint(); /** 指定XML编码 */ format.setEncoding("GBK"); writer= new XMLWriter(new FileWriter(new File(filename)), format); writer.write(document); writer.close(); /** 执行成功,需返回1 */ returnValue = 1; }catch(Exception ex){ ex.printStackTrace(); } return returnValue; } |
例10.4
|
说明: OutputFormat format = OutputFormat.createPrettyPrint(); 这句指定了格式化的方式为缩进式,则非紧凑式。 format.setEncoding("GBK"); 指定编码为GBK。 XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)),format); 这与前面两个方法相比,多加了一个OutputFormat对象,用于指定显示和编码方式。
|
10.6 总结
- 扩展标记语言XML是一种简单的数据存储语言,结构严谨,使用方便,在当前WEB开发领域所起的作用越来越大,应用越来越广泛。
- DOM4J是dom4j.org出品的一个开源XML解析包,性能优异,开发便捷。
14XML解析的更多相关文章
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- .NET Core中的认证管理解析
.NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...
- Html Agility Pack 解析Html
Hello 好久不见 哈哈,今天给大家分享一个解析Html的类库 Html Agility Pack.这个适用于想获取某网页里面的部分内容.今天就拿我的Csdn的博客列表来举例. 打开页面 用Fir ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- Asp.Net WebApi核心对象解析(下篇)
在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...
- 【知识必备】内存泄漏全解析,从此拒绝ANR,让OOM远离你的身边,跟内存泄漏say byebye
一.写在前面 对于C++来说,内存泄漏就是new出来的对象没有delete,俗称野指针:而对于java来说,就是new出来的Object放在Heap上无法被GC回收:而这里就把我之前的一篇内存泄漏的总 ...
- SQL Server 数据加密功能解析
SQL Server 数据加密功能解析 转载自: 腾云阁 https://www.qcloud.com/community/article/194 数据加密是数据库被破解.物理介质被盗.备份被窃取的最 ...
随机推荐
- hadoop分布式安装部署具体视频教程(网盘附配好环境的CentOS虚拟机文件/hadoop配置文件)
參考资源下载:http://pan.baidu.com/s/1ntwUij3视频安装教程:hadoop安装.flvVirtualBox虚拟机:hadoop.part1-part5.rarhadoop文 ...
- java web项目的部署
java web项目的部署 我刚开始学着编写java web项目,着实遇到不少麻烦,感觉JAVA真难侍候,好多东西都是手动.手动. 就拿这个web项目在tomcat上的部署来说吧.我在项目的build ...
- ZOJ3659 Conquer a New Region 并查集
Conquer a New Region Time Limit: 5 Seconds Memory Limit: 32768 KB The wheel of the history roll ...
- 关于编译(javac),import,package的再理解
1.若我们在A.java中用到了类B,当我们仅仅用 javac A.java 编译A时,编译器也会去寻找B,若类B依然是源文件,也会自动编译它.在使用javac和java命令时,有一个参数选项 -ve ...
- JLabel作为展现元素时需要注意的事项
如果没有内容,JLabel默认透明就无法作为点击区域了,所以为了让其可以响应鼠标事件需要设置 setOpaque(true) 这样就可以响应鼠标事件了 (吐槽一下,多年以前在大学做个web地图导航的网 ...
- BZOJ_1493_[NOI2007]项链工厂_Splay
BZOJ_1493_[NOI2007]项链工厂_Splay Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打算 ...
- 逻辑频道号---DVB NIT LCN
先介绍NIT,NIT描述如下: 有一点要注意,NIT是对大网的描述,即NIT并不是描述当前的流,而是描述大网的某些或者全部流.如下图,TS流描述1-6共对6个频点不同的TS流进行了描述,具体对哪一个流 ...
- ECS服务器配置密钥登录及常用日志
一.介绍 1.SSH(22端口)是Secure Shell Protocol的简写,由IETF网络工作小组(Network Working Group)制定:在进行数据传输之前,SSH先对联机数据包通 ...
- SQL Server2012 T-SQL基础教程--读书笔记(1-4章)
SQL Server2012 T-SQL基础教程--读书笔记(1-4章) SqlServer T-SQL 示例数据库:点我 Chapter 01 T-SQL 查询和编程背景 1.3 创建表和定义数据的 ...
- WP8 中使用HTML Agility Pack与友盟分享SDK遇到的 System.Xml.XPath加载问题
今晚在尝试使用友盟最新的社交分享SDK时,按照官方Demo,并未做多少多少改动,就是去除了对微信.脸书和推特的分享.然后运行之后就一直报错 : {System.IO.FileLoadException ...