XML 技术是随着 Java 的发展而发展起来的。在 XML 出现之前对于简单的数据格式通常是存储在 ini 配置文件等文本文件中,复杂的格式则采用自定义的文件格式,因此对于每种文件格式都要有专门的解析程序。 XML 出现以后解决了这个问题,程序面对的是有固定格式的 XML 文件,只要通过标准 API 就可以进行 XML 文件的处理。
XML 文件在案例系统中应用是很广泛的,比如 ClientConfig.xml 、 ServerConfig.xml 文件就是使用 XML 文件来做配置文件的,元数据文件以及元数据加载器更是离不开 XML 。因此总结一下处理技术。
XML处理技术比较
在 Java 领域 XML 文件的技术大致分为两类: XML API 和 OXMapping 。 XML API 是 XML 处理的基础,可选技术包括 JDOM 、 Dom4j 等; OXMapping 是 Object-XML Mapping 的简称,这种技术隐藏了 XML 底层操作的细节,可以将 XML 文件映射成一个 JavaBean 对象,也可以把一个 JavaBean 对象保存成一个 XML 文件,可选技术 XStream 、 Digester 、 Castor 等。 XML API 和 OXMapping 的关系类似于 JDBC 和 ORMaping 的关系, OXMapping 内部实现使用 XML API 来完成,两种实现技术从不同的层面实现了 XML 的处理。
XML API
此类 XML 处理技术中最流行的莫过于 JDOM 和 Dom4j 了,二者的使用方式非常相似。不过 Dom4j 的优势比 JDOM 更明显一些:
DOM4J是dom4j.org出品的一个开源XML解析包,它的网站中这样定义:
Dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。
DOM4J使用起来非常简单。只要你了解基本的XML-DOM模型,就能使用。
dom4j是sourceforge.net上的一个开源项目,主要用于对XML的解析。从2001年7月发布第一版以来,已陆续推出多个版本。
dom4j专门针对Java开发,使用起来非常简单、直观,在Java界,dom4j正迅速普及。
可以到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异常,其他的包可以选择用之。
Dom4j 支持 XPath 等高级特性;
正是由于这些优点,很多开源项目都开始使用 Dom4j 做 XML 解析技术,本书也将使用 Dom4j 做为 XML 处理的首选。
OXMapping
使用 XML API 解析是略显烦琐的,受 ORMapping 技术的启发,人们发明了 OXMapping 技术,使用 OXMapping 技术,我们可以将 XML 文件映射成一个 JavaBean 对象,也可以把一个 JavaBean 对象保存成一个 XML 文件,这大大简化了我们的开发工作量,使得开发人员能更多的关注应用层面的东西。
开源世界中涌现出很多 OXMapping 框架,包括 XStream 、 Digester 、 Castor 等。 XStream 和 Digester 把映射的过程在代码中完成,而 Castor 则需要写一个和 Hibernate 中 cfg.xml 类似的映射配置文件。
与 Digester 比起来, XStream 的主要优点就是更加小巧,使用也更加方便,不过目前使用 Digester 是“开源名牌” Apache 下的子项目,网上可以参考的资料也比 XStream 多,好在 XStream 比较简洁,所以并不会对 XStream 造成太大影响。
============================================================================
一、利用dom4j解析xml
认识一下它的接口:
Attribute
Attribute定义了XML的属性
Branch
Branch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为
CDATA
CDATA 定义了XML CDATA 区域
CharacterData
CharacterData是一个标识借口,标识基于字符的节点。如CDATA,Comment, Text.
Comment
Comment 定义了XML注释的行为
Document
定义了XML文档
DocumentType
DocumentType 定义XML DOCTYPE声明
Element
Element定义XML 元素
ElementHandler
ElementHandler定义了 Element 对象的处理器
ElementPath
被 ElementHandler 使用,用于取得当前正在处理的路径层次信息
Entity
Entity定义 XML entity
Node
Node为所有的dom4j中XML节点定义了多态行为
NodeFilter
NodeFilter 定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate)
ProcessingInstruction
ProcessingInstruction 定义 XML 处理指令.
Text
Text 定义XML 文本节点.
Visitor
Visitor 用于实现Visitor模式.
XPath
XPath 在分析一个字符串后会提供一个XPath 表达式
看名字大致就知道它们的涵义如何了。
================================================================
具体实现技术:
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;
}
其中,reader的read方法是重载的,可以从InputStream, File, Url等多种不同的源来读取。得到的Document对象就带表了整个XML。
根据本人自己的经验,读取的字符编码是按照XML文件头定义的编码来转换。如果遇到乱码问题,注意要把各处的编码名称保持一致即可。
2. 取得Root节点
读取后的第二步,就是得到Root节点。熟悉XML的人都知道,一切XML分析都是从Root元素开始的。
public Element getRootElement(Document doc){
return doc.getRootElement();
}
3. 遍历XML树(暂时小结4种方法)
DOM4J提供至少3种遍历节点的方法:
1) 迭代所有子节点
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
Element element = (Element) i.next();
}
迭代名称为foo的节点,这招很牛可以准确定位指定类型的节点
for ( Iterator i = root.elementIterator(foo); i.hasNext();) {
Element foo = (Element) i.next();
}
迭代属性
for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {
Attribute attribute = (Attribute) i.next();
}
2)递归
递归也可以采用Iterator作为枚举手段,但文档中提供了另外的做法
public void treeWalk() {
treeWalk(getRootElement());
}
public void treeWalk(Element element) {
for (int i = 0, size = element.nodeCount(); i < size; i++) {
Node node = element.node(i);
if (node instanceof Element) {
treeWalk((Element) node);
} else { // do something....
}
}
}
3) Visitor模式(访问者模式),很方变!
最令人兴奋的是DOM4J对Visitor的支持,这样可以大大缩减代码量,并且清楚易懂。了解设计模式的人都知道,Visitor是GOF设计模式之一。其主要原理就是两种类互相保有对方的引用,并且一种作为Visitor去访问许多Visitable。我们来看DOM4J中的Visitor模式(快速文档中没有提供)
只需要自定一个类实现Visitor接口即可。+
public class MyVisitor extends VisitorSupport {
public void visit(Element element){
System.out.println(element.getName());
}
public void visit(Attribute attr){
System.out.println(attr.getName());
}
}
调用: root.accept(new MyVisitor())
Visitor接口提供多种Visit()的重载,根据XML不同的对象,将采用不同的方式来访问。上面是给出的Element和Attribute的简单实现,一般比较常用的就是这两个。VisitorSupport是DOM4J提供的默认适配器,Visitor接口的Default Adapter模式,这个模式给出了各种visit(*)的空实现,以便简化代码。
注意,这个Visitor是自动遍历所有子节点的。如果是root.accept(MyVisitor),将遍历子节点。我第一次用的时候,认为是需要自己遍历,便在递归中调用Visitor,结果可想而知。
4). XPath支持,我比较喜欢用这个方法解析xml,目的性强,灵活!
DOM4J对XPath有良好的支持,如访问一个节点,可直接用XPath选择。
public void bar(Document document) {
注意:括号内路径的写法
List list = document.selectNodes( //foo/bar );
for(int i=0;i<list.size();i++){
Element ee=(Element)list.get(i);
String name=ee.getName();
String value=ee.getText();
}
Node node = document.selectSingleNode(//foo/bar/author);
//Element elem = (Element)doc.selectSingleNode("//subA");
String name = node.valueOf( @name );
}
例如,如果你想查找XHTML文档中所有的超链接,下面的代码可以实现:
public void findLinks(Document document) throws DocumentException {
List list = document.selectNodes( //a/@href );
for (Iterator iter = list.iterator(); iter.hasNext(); ) {
Attribute attribute = (Attribute) iter.next();
String url = attribute.getValue();
}
}
5. 字符串与XML的转换
有时候经常要用到字符串转换为XML或反之,
XML转字符串
Document document = ...;
String text = document.asXML();
字符串转XML
String text = “<person> <name>James</name> </person>“;
Document document = DocumentHelper.parseText(text);
6 、用XSLT转换XML
public Document styleDocument( Document document, String stylesheet ) throws Exception {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource( stylesheet )
);
// now lets style the given document
DocumentSource source = new DocumentSource( document );
DocumentResult result = new DocumentResult();
transformer.transform( source, result );
// return the transformed document
Document transformedDoc = result.getDocument();
return transformedDoc;
}
7. 创建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;
}
8. 文件输出
一个简单的输出方法是将一个Document或任何的Node通过write方法输出
FileWriter out = new FileWriter( foo.xml );
document.write(out);
如果你想改变输出的格式,比如美化输出或缩减格式,可以用XMLWriter类
public void write(Document document) throws IOException {
XMLWriter writer = new XMLWriter(
new FileWriter( output.xml )
);
writer.write( document );
writer.close();
// 美化格式
OutputFormat format = OutputFormat.createPrettyPrint();
writer = new XMLWriter( System.out, format );
writer.write( document );
// 缩减格式
format = OutputFormat.createCompactFormat();
writer = new XMLWriter( System.out, format );
writer.write( document );
}
这里有两点需要注意的:
( 1 ) OutputFormat format = OutputFormat.createPrettyPrint()
XML 通常是需要人阅读的, Dom4j 默认的生成格式是紧缩格式的,这样可以减少空间占用,但是带来的缺点就是文件格式非常难看,因此我们采用锁紧格式进行输出。
( 2 ) format.setEncoding("GB2312")
Dom4j 默认的编码格式是“ UTF-8 ”,这在输出中文字符的时候会有问题,因此我们改成“ GB2312 ”格式。
这里使用了 Dom4j 提供的工具类 DocumentHelper 提供的 createElement 方法来创建一个节点,这个工具类还有 public static CDATA createCDATA(String text) 、 public static Comment createComment(String text) 、 public static Entity createEntity(String name, String text) 等方法可以帮助我们更快的创建节点。 DocumentHelper 还提供了 parseText 方法,可以直接将字符串解析成 Documen 对象。
9、修改节点、删除节点(略,写的太累拉)
Element有几个重要的方法:
addComment:添加注释
addAttribute:添加属性
addElement:添加子元素
addText:添加节点值
setText:修改节点值
setvalue:修改节点值
remove:删除节点值
===========================================================
二、利用xstream实现JAVABEAN和XML交互
在使用 XStream 之前首先到 http://xstream.codehaus.org 下载 XStream 的最新版本,然后把 XSteam***.jar 和 xpp3-***.jar 导入到 ClassPath 下,然后就可以使用了,当然不加入 xpp3-***.j
ar 也可以,我们可以使用 DomDriver 做为 XML 解析驱动(只要在实例化 XStream 的时候使用 new XStream(new DomDriver()) 即可),不过 Xpp3 为 XStream 提供的一个很有效率的 XML pull-parser 实现,推荐使用,可以提高解析的效率。
XStream是个很小的开源项目,所以它能实现的功能也就很有限,它只能包装简单类型的元素进行转换,复杂类型的,比如Calendar,Date等类型则需要用户自己实现Converter。
还有,XStream对xml的操作并不好,比如想把一个子节点变成属性就是一个很复杂的工作,但是大家平时用于测试的话,看看对象中到底存着什么数据,还是必要的。
XML 的解析
我们有一个记录书籍进行的 XML 文件:
<book>
<name>J2EE Guide Book</name>
<author>
<name>Jerry</name>
<email>Jerry@mail.com</email>
</author>
</book>
为了解析此 XML 文件,我们首先创建代表书籍和人员的两个 JavaBean 。
代码 5 . 3 人员和书籍的 JavaBean
public class BookInfo
{
private String name;
private PersonInfo author;
public PersonInfo getAuthor()
{
return author;
}
public void setAuthor(PersonInfo author)
{
this.author = author;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
public class PersonInfo
{
private String name;
private String email;
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
然后我们就可以进行文件的解析了,这也是重头戏:
代码 5 . 4 XStream 的 XML 解析
XStream xstream = new XStream();
xstream.alias("book", BookInfo.class);
xstream.alias("author", PersonInfo.class);
InputStream inStream = XStreamDemo.class
.getResourceAsStream("/com/cownew/Char0503/Books.xml");
InputStreamReader reader = new InputStreamReader(inStream);
BookInfo book = (BookInfo) xstream.fromXML(reader);
StringBuffer sb = new StringBuffer();
sb.append(book.getName()).append(" 的作者 ");
sb.append(book.getAuthor().getName()).append(" 的 Email 为 :");
sb.append(book.getAuthor().getEmail());
System.out.println(sb);
运行结果:
J2EE Guide Book 的作者 Jerry 的 Email 为 :Jerry@mail.com
由于 book 节点和 author 节点对应的数据类型是我们的自定义类型,因此我们必须首先向 XStream 注册这两个类型 :
xstream.alias("book", BookInfo.class);
xstream.alias("author", PersonInfo.class);
由于我们是使用 XStream 解析已有的 XML 文件,因此我们必须让 XStream 知道标签对应的类型是什么,如果我们是使用 XStream 进行 XML 文件的生成,那么我们甚至无需向 XStream 注册别名即可进行文件解析。
注册完类型以后,调用 XStream 类的 fromXML 方法即可把 XML 解析成 JavaBean 对象,无需额外的操作。
XML 文件的保存
我们不仅需要解析 XML 文件,有的时候还需要将数据保存到 XML 文件, XStream 同样能很好的完成,并且能更体现出 XStream 的强大。
代码 5 . 5 XStream 中 XML 的保存
List bookList = new ArrayList();
PersonInfo p1 = new PersonInfo();
p1.setName("Tom");
p1.setEmail("Tom@mail.com");
PersonInfo p2 = new PersonInfo();
p2.setName("Jerry");
p2.setEmail("Jerry@mail.com");
BookInfo book1 = new BookInfo();
book1.setName("About Face");
book1.setAuthor(p1);
BookInfo book2 = new BookInfo();
book2.setName("UI Design");
book2.setAuthor(p2);
bookList.add(book1);
bookList.add(book2);
XStream xstream = new XStream();
String xml = xstream.toXML(bookList);
System.out.println(xml);
List list = (List) xstream.fromXML(xml);
for(int i=0,n=list.size();i<n;i++)
{
BookInfo book = (BookInfo) list.get(i);
StringBuffer sb = new StringBuffer();
sb.append(book.getName()).append(" 的作者 ");
sb.append(book.getAuthor().getName()).append(" 的 Email 为 :");
sb.append(book.getAuthor().getEmail());
System.out.println(sb);
}
运行结果:
<list>
<com.cownew.Char0503.BookInfo>
<name>About Face</name>
<author>
<name>Tom</name>
<email>Tom@mail.com</email>
</author>
</com.cownew.Char0503.BookInfo>
<com.cownew.Char0503.BookInfo>
<name>UI Design</name>
<author>
<name>Jerry</name>
<email>Jerry@mail.com</email>
</author>
</com.cownew.Char0503.BookInfo>
</list>
About Face 的作者 Tom 的 Email 为 :Tom@mail.com
UI Design 的作者 Jerry 的 Email 为 :Jerry@mail.com
不可思议吧!我们就是像在序列化一样把 JavaBean “序列化”为 XML 格式字符串,然后又轻松的将 XML 格式字符串“反序列化”为 JavaBean 。
不过美中不足的就是“ <com.cownew.Char0503.BookInfo> ”这个标签显得有点罗嗦。解决方式很简单,使用 5.3.1 一节中提到的 alias 方法就可以办到:
将 xstream.alias("book", BookInfo.class);如:xstream.alias("book",com.nownew.Char0503.BookInfo.class) 添加到 XStream xstream = new XStream(); 之后,然后重新运行:
<list>
<book>
<name>About Face</name>
<author>
<name>Tom</name>
<email>Tom@mail.com</email>
</author>
</book>
<book>
<name>UI Design</name>
<author>
<name>Jerry</name>
<email>Jerry@mail.com</email>
</author>
</book>
</list>
分享到:
相关推荐
DOM4J和XStream是Java开发中处理XML数据的两个重要工具,它们分别在XML文档解析和Java对象到XML的转换方面提供了强大的功能。 DOM4J是一个非常灵活且功能丰富的XML处理库,它提供了多种方式来操作XML文档,包括读取...
解压后有一个文件夹(包含了dom4j和XStream的简单示例),一个dom4j.jar(用dom4j只需要把这个添加到项目里面),一个xstream-1.4.8的jar包、源码、说明文档.zip(用xstream就解压这个包然后放到项目里面)
XStream和DOM4J是Java中处理XML的两个重要库,它们各自有着独特的特性和优势。 **XStream** XStream是一款开源的Java库,它将Java对象与XML进行相互转换。它的主要优点在于使用简单,通过简单的API即可实现对象到...
在Java中,DOM4J是一个强大的、灵活的处理XML的库,提供了全面的功能来读取、写入、修改XML文档。本教程将深入讲解如何使用DOM4J进行高效XML解析,并通过一个简单的DEMO程序进行演示。 首先,我们需要了解DOM4J的...
在提供的"dom+xstream"压缩包中,可能包含了这两个库的jar文件,以及示例代码或者测试用例,用于演示如何将DOM4J解析的XML数据通过XStream进行序列化和反序列化。用户解压后可以直接引入到自己的项目中,无需额外...
描述中提到的"java xml解析所需要的包",通常包括了DOM4J库和其他辅助库,如XStream。XStream是一个用于Java的XML序列化库,能够将Java对象直接转换为XML,反之亦然。这在需要将数据持久化到XML或者从XML中恢复数据...
本主题聚焦于四种不同的Java库——XStream、Dom4j、Groovy以及JDOM,它们都是用来解析和操作XML文档的工具。 1. **XStream**: XStream是一个Java库,它提供了将Java对象序列化为XML,以及从XML反序列化回Java对象...
在IT领域,XML...在处理XML的项目中,dom4j和XStream是强大的工具,可以大大提高开发效率。在给定的文件列表中,`dom4j-1.6.1.jar`和`xstream.jar`分别是这两个库的可执行文件,可以直接引入到Java项目中使用。
`dom4j-1.6.1.jar`是DOM4J的一个版本,包含所有必要的类和方法来处理XML任务。 3. XStream: XStream是另一个强大的Java库,用于XML序列化和反序列化。它可以将Java对象直接转换为XML,反之亦然。这在需要将Java...
由于先前有已经有上传过dom4j和xtream的两个jar包了,但最近看到之前那个下载积分变成27了,这可能是csdn的bug,我原先都是定义1个积分,因为csdn现在没有0积分了,最低就是1积分!
在Java中,处理XML的库有很多,其中Dom4j是一个功能强大且灵活的库,它提供了对XML的全面支持,包括读取、写入、修改以及XPath查询等操作。本文将深入探讨Dom4j库的封装与解析,并结合实际案例进行讲解。 首先,让...
DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活且高效的API,使得XML的解析、创建、修改和查询变得简单。DOM4J在Java社区中被广泛使用,尤其是在那些需要处理大量XML数据的应用中。这个压缩包包含两个...
4. **易于集成**:DOM4J与许多其他Java库如JAXB、XStream等兼容,便于XML与其他数据格式的转换。 **DOM4J与DOM的对比** 1. **内存占用**:DOM4J通常占用更少的内存,因为它在解析XML时采用了一些优化策略。 2. **...
至于"dom4jxml 修改"这个文件名,可能是压缩包中包含的一个示例,展示了如何使用DOM4J2来修改XML文件。这个文件可能包含了XML的原始版本和经过DOM4J处理后的修改版本,用于演示DOM4J的功能和操作步骤。 总结来说,...
在这个压缩包中包含的三个关键组件——XStream.jar、dom4j.jar和xpp3-1.1.4c.jar,都是Java开发者在处理XML时不可或缺的工具。 1. **XStream.jar**: XStream是一款强大的Java库,用于将Java对象序列化为XML,以及...
7. **集成性**:DOM4J与其他Java库如JAXB(Java Architecture for XML Binding)、XStream等有良好的集成,便于XML与Java对象之间的映射。 在实际应用中,开发者通常会将**dom4j-1.6.1.jar** 包导入到项目的类路径...
XStream不仅能够将Java对象转换为XML,还可以反向将XML转换回Java对象,极大地简化了对象与XML之间的序列化和反序列化过程。 XStream库是由Johannes Lehtinen创建的一个开源项目,它是基于Java的,可以处理复杂的...
- 转换XML到Java对象:DOM4J可以结合JAXB或XStream进行对象-XML的转换。 8. **最佳实践**: - 使用DOM4J的迭代器遍历XML,以降低内存消耗。 - 对于大型XML,优先考虑SAX或StAX解析。 - 注意异常处理,确保程序...
本篇将详细讲解XML的解析方式及其在Java中的应用,特别是如何使用XStream库进行JavaBean与XML之间的互转。 1. **XML解析方式** - DOM解析:Document Object Model,它一次性加载整个XML文档到内存,形成一棵树形...
标题中的“XStream实现Object与XML转换解决方案”指的是一个Java库——XStream,它提供了一种简单的方法来序列化和反序列化Java对象到XML,反之亦然。这个库广泛用于将程序数据保存到XML文件或者从XML数据恢复对象,...