XML
				技术是随着
				Java
				的发展而发展起来的。在
				XML
				出现之前对于简单的数据格式通常是存储在
				ini
				配置文件等文本文件中,复杂的格式则采用自定义的文件格式,因此对于每种文件格式都要有专门的解析程序。
				XML
				出现以后解决了这个问题,程序面对的是有固定格式的
				XML
				文件,只要通过标准
				API
				就可以进行
				XML
				文件的处理。
		
		
				XML
				文件在案例系统中应用是很广泛的,比如
				ClientConfig.xml
				、
				ServerConfig.xml
				文件就是使用
				XML
				文件来做配置文件的,元数据文件以及元数据加载器更是离不开
				XML
				。因此本章将系统讲解一下
				XML
				文件的处理技术。
		
		
				
						
								1.1
								   
						
				
				
						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
				比
				Dom4j
				更加灵活和具有可扩展性;
		
		
				Dom4j
				的性能表现比
				JDOM
				好;
		
		
				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
				造成太大影响。
		
		
		
				
						
								1.2
								   
						
				
				
						Dom4j的使用
		
		
				Dom4j
				是一个易用的、开源的库,用于
				XML
				,
				XPath
				和
				XSLT
				。它应用于
				Java
				平台,采用了
				Java
				集合框架并完全支持
				DOM
				,
				SAX
				和
				JAXP
				。
				Dom4j
				是
				sourceforge.net
				上的一个开源项目,地址为
				http://sourceforge.net/projects/dom4j
				。
		
		
				Dom4j
				里基于接口编程是一个非常显著的优点,下面是其主要的接口的继承体系结构图:
		
		
				
						
						
								
								
								
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
								
								
								
								
								
								
						
						
								
								
						
				
		
		
				
						图
						
								
										5
								
								.
								
										1
								
						
				
		
		
				这些接口大部分都是定义在包
				org.dom4j
				中,下面简单介绍各个接口的意义:
		
		
				
						表
						
								
										5
								
								.
								
										1
								
								 Dom4j
						
						主要接口
				
		
		
				
						
								
										| 
												 
														Node
												 
										 | 
										
												 
														Node
														为是
														dom4j
														中所有的
														XML
														节点的基类型接口
														
																
																
														
												 
										 | 
								
								
										| 
												 
														Attribute
												 
										 | 
										
												 
														Attribute
														定义了
														XML
														的属性
														
																
																
														
												 
										 | 
								
								
										| 
												 
														Branch
												 
										 | 
										
												 
														Branch
														为能够包含子节点的节点如
														XML
														元素
														(Element)
														和文档
														(Docuemnts)
														定义了一个公共的行为
														
																
																
														
												 
										 | 
								
								
										| 
												 
														Document
												 
										 | 
										
												 
														定义了
														XML
														文档
														
																
																
														
												 
										 | 
								
								
										| 
												 
														Element
												 
										 | 
										
												 
														Element
														定义
														XML 
														元素
														
																
																
														
												 
										 | 
								
								
										| 
												 
														DocumentType
												 
										 | 
										
												 
														DocumentType 
														定义
														XML DOCTYPE
														声明
														
																
																
														
												 
										 | 
								
								
										| 
												 
														Entity
												 
										 | 
										
												 
														Entity
														定义
														 XML entity
												 
										 | 
								
								
										| 
												 
														CharacterData
												 
										 | 
										
												 
														CharacterData
														是一个标识借口,标识基于字符的节点。如
														CDATA
														,
														Comment, Text
												 
										 | 
								
								
										| 
												 
														CDATA
												 
										 | 
										
												 
														CDATA 
														定义了
														XML CDATA 
														区域
														
																
																
														
												 
										 | 
								
								
										| 
												 
														Comment
												 
										 | 
										
												 
														Comment 
														定义了
														XML
														注释的行为
														
																
																
														
												 
										 | 
								
								
										| 
												 
														Text
												 
										 | 
										
												 
														Text 
														定义
														XML 
														文本节点
														
																
																
														
												 
										 | 
								
								
										| 
												 
														ProcessingInstruction
												 
										 | 
										
												 
														ProcessingInstruction 
														定义
														 XML 
														处理指令
														
																
																
														
												 
										 | 
								
						
				
		 
		
				
						 
				
		
		
				读取
				XML
				文件
		
		
				在
				XML
				应用中,最常用的莫过于
				XML
				文件的解析读取了,
				Dom4j
				提供了多种读取
				XML
				文档的方式,包括
				Dom
				树遍历、
				Visitor
				方式和
				XPath
				方式。
		
		
				无论哪种方式,我们首先都要根据
				xml
				文件构造一个
				Document
				对象:
		
		
				
						SAXReader reader = new SAXReader();
				
		
		
				
						Document document = reader.read(new File(fileName));
				
		
		
				这里我们选用了
				SAXReader
				做为
				XML
				读取器,我们同样也可以选择
				DOMReader
				做为
				XML
				读取器:
		
		
				
						SAXReader reader = new DOMReader();
				
		
		
				
						Document document = reader.read(new File(fileName));
				
		
		
				其中
				reader
				的
				read
				方法有多个重载方法,可以从
				InputStream, File, URL
				等多种不同的源来读取
				XML
				文档。
		
		
				(
				1
				)
				Dom
				树遍历
		
		
				这种读取方式中把
				Dom
				看成一个普通的树,要读取
				XML
				中某个节点的值,只要采用数据结构中的树遍历算法定位到需要读取的节点即可。
		
		
				要便利
				Dom
				树,首先要取得树的根节点:
		
		
				Element root = document.getRootElement();
		
		
				取得根节点以后就可以一级一级的向下读了:
		
		
				
						
								// 
						
						遍历所有子节点
				
		
		
				
						for ( Iterator i = root.elementIterator(); i.hasNext(); ) 
				
		
		
				
						{
				
		
		
				
						      
						
								 Element element = (Element) i.next();
						
				
		
		
				
						      
						
								 // do something
						
				
		
		
				
						   
						
								 }
						
				
		
		
				
						   
						
								 // 
						
						遍历名称为“
						
								foo
						
						”的节点
				
		
		
				
						
								for ( Iterator i = root.elementIterator(
						
						“
						
								foo
						
						”
						
								); i.hasNext();) 
						
				
		
		
				
						{
				
		
		
				
						      
						
								 Element foo = (Element) i.next();
						
				
		
		
				
						      
						
								 // do something
						
				
		
		
				
						   
						
								 }
						
				
		
		
				
						   
						
								 // 
						
						遍历属性
				
		
		
				
						for ( Iterator i = root.attributeIterator(); i.hasNext(); ) 
				
		
		
				
						{
				
		
		
				
						      
						
								 Attribute attribute = (Attribute) i.next();
						
				
		
		
				
						      
						
								 // do something
						
				
		
		
				
						}
				
		
		
				(
				2
				)
				Visitor
				方式
		
		
				Dom
				树遍历是最普通,也是最常用的
				XML
				读取方式,其他的
				XML
				解析引擎,比如
				JDom
				等,也是使用这种方式进行
				XML
				的读取。不过
				Dom4j
				提供了另外一种读取方式,那就是
				Visitor
				方式。这种方式实现了
				Visitor
				模式,调用者只要编写一个
				Visitor
				就可以了。
				Visitor
				模式使得访问者易于增加新的操作,同时使访问者集中相关的操作而分离无关的操作。
		
		
				编写的
				Visitor
				必须实现
				org.dom4j.Visitor
				接口,
				Dom4j
				还提供了一个
				Default Adapter
				模式的默认适配器
				org.dom4j.VisitorSupport
				。
		
		
				
						public class DemoVisitor extends VisitorSupport 
				
		
		
				
						{
				
		
		
				
						public void visit(Element element)
				
		
		
				
						{
				
		
		
				
						System.out.println(element.getName());
				
		
		
				
						}
				
		
		
				
						public void visit(Attribute attr)
				
		
		
				
						{
				
		
		
				
						System.out.println(attr.getName());
				
		
		
				
						}
				
		
		
				
						}
				
		
		
				然后在要开始遍历的节点调用此
				Visitor
				即可:
				
						
						
				
		
		
				
						root.accept(new DemoVisitor ())
				
		
		
				此方式需要遍历所有的节点和元素,因此速度会稍慢一些。
		
		
				(
				3
				)
				XPath
				方式
		
		
				Dom4j
				最吸引人的特性莫过于对
				XPath
				的集成支持了,这个特性并不是所有的
				XML
				解析引擎都支持的,但是确实一个非常有用的特性。
		
		
				XPath 
				是寻址、搜索和匹配文档的各个部分的语言。它使用路径标记法来指定和匹配文档的各个部分,该标记法与文件系统和
				 URL 
				中使用的类似。例如,
				XPath:/x/y/z 
				搜索文档的根节点
				 x
				,其下存在节点
				 y
				,其下存在节点
				 z
				。该语句返回与指定路径结构匹配的所有节点。
				/x/y/* 
				返回父节点为
				 x 
				的
				 y 
				节点下的任何节点。
				/x/y[@name=a] 
				匹配所有父节点为
				 x 
				的
				 y 
				节点,其属性称为
				 name
				,属性值为
				 a
				。
		
		
				XPath
				大大简化了
				XML
				的寻址操作,使用者只要通过匹配表达式告诉引擎要匹配文档的哪些部分即可,具体的匹配工作由
				XPath
				引擎来完成。这种方式更加接近于人类的自然思维方式。我们来看一个实际的例子:
		
		
				有一个
				XML
				文件记录了一个部门的基本情况:
		
		
				
						<?xml version="1.0" encoding="GB2312"?>
				
		
		
				
						<department>
				
		
		
				
						
								
										     <name>
						
						开发部
						
								</name>
						
				
		
		
				
						
								
										     <level>2</level>
						
				
		
		
				
						
								
										     <employeeList>
						
				
		
		
				
						
								
										         <employee number="001" name="Tom" />
						
				
		
		
				
						
								
										         <employee number="002" name="Jim" />
						
				
		
		
				
						
								
										         <employee number="003" name="Lily" />
						
				
		
		
				
						
								
										     </employeeList>
						
				
		
		
				
						</department>
				
		
		
				name
				代表部门名称,
				level
				为部门的级别,
				employeeList
				下是部门所有的员工列表。下面编写一个程序读取此文件并打印出部门的信息。
		
		
				
						代码
						
								
										5
								
								.
								
										1
								
								 XPath
						
						演示
				
		
		
				
						
								InputStream inStream = null;
						
				
				
						
								try
						
				
				
						
								{
						
				
				
						
								
										
												     inStream = Dom4jDemo01.class.getResourceAsStream(
										
												
												
										
								
						
				
				
						
								"/com/cownew/Char0502/Department01.xml");
						
				
				
						
								
										
												     SAXReader reader = new SAXReader();
								
						
				
				
						
								
										
												     Document doc = reader.read(new InputStreamReader(inStream));
								
						
				
				
						
								
										
												     Node nameNode = doc.selectSingleNode("//department/name");
								
						
				
				
						
								
										
												     System.out.println("
								
								部门名称
								
										:" + nameNode.getText());
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												     Node levelNode = doc.selectSingleNode("//department/level");
								
						
				
				
						
								
										
												     System.out.println("
								
								部门级别
								
										:" + levelNode.getText());
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												     List employeeNodeList = doc
								
						
				
				
						
								
										
												                   .selectNodes("//department/employeeList/employee");
								
						
				
				
						
								
										
												     System.out.println("
								
								部门下属雇员
								
										:");
								
						
				
				
						
								
										
												     for (int i = 0, n = employeeNodeList.size(); i < n; i++)
								
						
				
				
						
								
										
												     {
								
						
				
				
						
								
										
												         DefaultElement employeeElement = (DefaultElement) employeeNodeList
								
						
				
				
						
								
										
												                            .get(i);
								
						
				
				
						
								
										
												         String name = employeeElement.attributeValue("name");
								
						
				
				
						
								
										
												         String number = employeeElement.attributeValue("number");
								
						
				
				
						
								
										
												         System.out.println(name + "
								
								,工号
								
										:" + number);
								
						
				
				
						
								
										
												     }
								
						
				
				
						
								} finally
						
				
				
						
								{
						
				
				
						
								
										
												     ResourceUtils.close(inStream);
								
						
				
				
						
								}
						
				
		 
		
				运行结果
				:
		
		
				
						部门名称
						
								:
						
						开发部
				
		
		
				
						部门级别
						
								:2
						
				
		
		
				
						部门下属雇员
						
								:
						
				
		
		
				
						
								Tom
						
						,工号
						
								:001
						
				
		
		
				
						
								Jim
						
						,工号
						
								:002
						
				
		
		
				
						
								Lily
						
						,工号
						
								:003
						
				
		
		
				
						 
				
		
		
				使用
				XPath
				以后,我们只要使用“
				//department/name
				”这种非常清晰的方式就可以直接定位到具体的节点。
				XPath
				方式中定位单个节点使用
				selectSingleNode
				方法,而定位多节点则使用
				selectNodes
				方法。
		
		
				案例系统中所有的
				XML
				文件都是使用
				XPath
				方式进行解析的,包括
				ClientConfig.java
				、
				ServerConfig.java
				、
				EntityMetaDataParser.java
				等。
		
		
				XML
				文件的创建
				
						
						
				
		
		
				Dom4j
				中
				XML
				文件的创建和其他的
				XML
				引擎类似,首先以
				Document
				的根节点为基础构造出一棵节点树,然后调用相应的
				IO
				类库就可以将
				XML
				文件保存到适当的介质中了。
		
		
				下面演示一下生成上文提到的那个部门信息
				XML
				文件的过程
				:
				
						
						
				
		
		
				
						代码
						
								
										5
								
								.
								
										2
								
						
						
								 XML
						
						创建演示
				
		
		
				
						
								import java.io.FileWriter;
						
				
				
						
								import java.io.IOException;
						
				
				
						
								
										 
								
						
				
				
						
								import org.dom4j.Document;
						
				
				
						
								import org.dom4j.DocumentHelper;
						
				
				
						
								import org.dom4j.Element;
						
				
				
						
								import org.dom4j.io.OutputFormat;
						
				
				
						
								import org.dom4j.io.XMLWriter;
						
				
				
						
								
										 
								
						
				
				
						
								public class Dom4jDemo02
						
				
				
						
								{
						
				
				
						
								
										
												     public static void main(String[] args)
								
						
				
				
						
								
										
												     {
								
						
				
				
						
								
										
												         // 
								
								创建文档对象
						
				
				
						
								
										
												         Document document = DocumentHelper.createDocument();
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												         // 
								
								添加根节点
								
										"department"
								
						
				
				
						
								
										
												         Element departElement = document.addElement("department");
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												         // 
								
								添加
								
										"name"
								
								节点
						
				
				
						
								
										
												         Element departNameElement = DocumentHelper.createElement("name");
								
						
				
				
						
								
										
												         departNameElement.setText("
								
								开发部
								
										");
								
						
				
				
						
								
										
												         departElement.add(departNameElement);
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												         // 
								
								添加
								
										"level"
								
								节点
						
				
				
						
								
										
												         Element departLevelElement = DocumentHelper.createElement("level");
								
						
				
				
						
								
										
												         departLevelElement.setText("2");
								
						
				
				
						
								
										
												         departElement.add(departLevelElement);
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												         // 
								
								添加员工列表
								
										"employeeList"
								
								节点
						
				
				
						
								
										
												         Element employeeElementList = DocumentHelper
								
						
				
				
						
								
										
												                   .createElement("employeeList");
								
						
				
				
						
								
										
												         departElement.add(employeeElementList);
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												         // 
								
								添加员工节点
								
										"employee"
								
						
				
				
						
								
										
												         Element emp1Element = DocumentHelper.createElement("employee");
								
						
				
				
						
								
										
												         emp1Element.addAttribute("number", "001");
								
						
				
				
						
								
										
												         emp1Element.addAttribute("name", "Tom");
								
						
				
				
						
								
										
												         employeeElementList.add(emp1Element);
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												         Element emp2Element = DocumentHelper.createElement("employee");
								
						
				
				
						
								
										
												         emp2Element.addAttribute("number", "002");
								
						
				
				
						
								
										
												         emp2Element.addAttribute("name", "Jim");
								
						
				
				
						
								
										
												         employeeElementList.add(emp2Element);
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												         Element emp3Element = DocumentHelper.createElement("employee");
								
						
				
				
						
								
										
												         //
								
								添加属性
						
				
				
						
								
										
												         emp3Element.addAttribute("number", "003");
								
						
				
				
						
								
										
												         emp3Element.addAttribute("name", "Lily");
								
						
				
				
						
								
										
												         employeeElementList.add(emp3Element);
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												         try
								
						
				
				
						
								
										
												         {
								
						
				
				
						
								
										
												              writeToFile(document, "c:/department.xml");
								
						
				
				
						
								
										
												         } catch (IOException e)
								
						
				
				
						
								
										
												         {
								
						
				
				
						
								
										
												              e.printStackTrace();
								
						
				
				
						
								
										
												         }
								
						
				
				
						
								
										
												     }
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												     private static void writeToFile(Document document, String file)
								
						
				
				
						
								
										
												              throws IOException
								
						
				
				
						
								
										
												     {
								
						
				
				
						
								
										
												         // 
								
								美化格式
						
				
				
						
								
										
												         OutputFormat format = OutputFormat.createPrettyPrint();
								
						
				
				
						
								
										
												         format.setEncoding("GB2312");
								
						
				
				
						
								
										
												         XMLWriter writer = null;
								
						
				
				
						
								
										
												         try
								
						
				
				
						
								
										
												         {
								
						
				
				
						
								
										
												              writer = new XMLWriter(new FileWriter(file), format);
								
						
				
				
						
								
										
												              writer.write(document);
								
						
				
				
						
								
										
												         } finally
								
						
				
				
						
								
										
												         {
								
						
				
				
						
								
										
												              if (writer != null)
								
						
				
				
						
								
										
												                   writer.close();
								
						
				
				
						
								
										
												         }
								
						
				
				
						
								
										
												     }
								
						
				
				
						
								}
						
				
		 
		
				运行以后就可以在
				c:/
				下发现生成了和
				5.2.1
				的文件内容一样的
				department.xml
				了。
		
		
				这里有两点需要注意的:
		
		
				(
				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
				对象。
		
		
		
				
						
								1.3
								   
						
				
				
						XStream的使用
		
		
				在使用
				XStream
				之前首先到
				http://xstream.codehaus.org
				下载
				XStream
				的最新版本,然后把
				XSteam***.jar
				和
				xpp3-***.jar
				导入到
				ClassPath
				下,然后就可以使用了,当然不加入
				xpp3-***.jar
				也可以,我们可以使用
				DomDriver
				做为
				XML
				解析驱动(只要在实例化
				XStream
				的时候使用
				new XStream(new DomDriver())
				即可),不过
				Xpp3
				为
				XStream
				提供的一个很有效率的
				XML pull-parser
				实现,推荐使用,可以提高解析的效率。
		
		
				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 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>
				
		
		
				
						
								About Face
						
						的作者
						
								Tom
						
						的
						
								Email
						
						为
						
								:Tom@mail.com
						
				
		
		
				
						
								UI Design
						
						的作者
						
								Jerry
						
						的
						
								Email
						
						为
						
								:Jerry@mail.com