`
请输入用户名
  • 浏览: 45916 次
  • 性别: Icon_minigender_1
  • 来自: martian
社区版块
存档分类
最新评论

基于dom4j编写的xml数据源操作类

    博客分类:
  • java
阅读更多
package test;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * 基于dom4j编写的xml数据源操作类,<p>可以将一个对象组织到xml文件中,
 * 如: outputDocUTF8ToFile(CreateXmlBaseObjectArray(person),"test.xml");</p><p>
 * 也可以将该xml中的内容读出来,并根据其中内容生成相应的对象,
 * 如: Object[] personFromXml = getObjectFromXml("test.xml");</p>
 * @author qihigh 2010.12.17
 *
 */
public class XmlMethodByDom4j {
	
	public static void main(String args[]) throws Throwable{
		Student[] person = {new Student("用户名",20,"爷们","春哥纯爷们","扩展"),
				   new Student("第二",25,"爷们c","春哥纯爷们","扩展2")};
		outputDocUTF8ToFile(CreateXmlBaseObjectArray(person),"test.xml");
		
		Object[] personFromXml = getObjectFromXml("test.xml");
		for(Object personXml : personFromXml){
			System.out.println(((Student) personXml).getUserName()+personXml);
		}
		
	}
	/**
	 * 把一个object数组写成xml形式
	 * @param objs
	 * @return objcet构造的xml整体的document
	 */
	public static Document CreateXmlBaseObjectArray(Object[] objs){
		if(objs.length == 0 || objs == null){
			return null;
		}
		Document doc = DocumentHelper.createDocument();
		//根节点 采用的第一个对象的class的name(其实所有的都一样)
		//当用objs.getClass()时候节点为 <[Ltest.Person;s>
		Element root = doc.addElement(objs[0].getClass().getName()+"s");
		for(Object o : objs){
			CreateXmlNode(o,root);
		}
		return doc;
	}
	/**
	 * 在给定的root 下构造整个obj xml树。
	 * @param 构建xml基于的obj
	 * @param 要构建的root
	 */
	private static void CreateXmlNode(Object obj,Element root){
		if(obj != null && !"".equals(obj)){
			//获取这个对象的所有属性(person 的所有属性)
			Map<String,String> attMap = getAttributeMap(obj);
			//节点属性
			String nodeClassName = obj.getClass().getName();//类的全称test.student
			String[] nodeNameDetail = nodeClassName.split("[.]");//类的全称详细描述数组.用的正则表达式
			String nodeName = nodeNameDetail[nodeNameDetail.length-1];//类的名字,比如student
			//节点的名字为类的名字,紧跟属性为类的全称
			Element studentName = root.addElement(nodeName).addAttribute("class", nodeClassName);
			//节点内部属性
			for(String key:attMap.keySet()){
				String value = attMap.get(key);
				Element tempEle = studentName.addElement(key);
				tempEle.setText(value);
			}
		}
	}
	/** 输出doc到标准输出流GBK,不好用 还是utf8 */
	public static void outputDocGBK(Document doc){
		if(doc == null || "".equals(doc)) 
			throw new NullPointerException("doc内容不能为空");
		outputDoc(doc,"GBK");
	}
	/** 输出doc到标准输出流UTF8 */
	public static void outputDocUTF8(Document doc){
		if(doc == null || "".equals(doc)) 
			throw new NullPointerException("doc内容不能为空");
		outputDoc(doc,"UTF-8");
	}
	/** 输出doc到标准输出流UTF8到文件 */
	public static void outputDocUTF8ToFile(Document doc,String fileName){
		if(doc == null || "".equals(doc)) 
			throw new NullPointerException("doc内容不能为空");
		outputDocToFile(doc,"UTF-8",fileName);
	}
	/** 输出doc到标准输出流 */
	private static void outputDoc(Document doc,String formatWay){
		  try{
			  OutputFormat format = new OutputFormat("	",true);
			  format.setEncoding(formatWay);
			  
			  XMLWriter xmlWriter = new XMLWriter(new PrintWriter(System.out),format);
			  xmlWriter.write(doc);
			  xmlWriter.close();
		  }catch (IOException e) {
			e.printStackTrace();
		  }
	}
	/**
	 * 输出到文件
	 */
	private static void outputDocToFile(Document doc,String formatWay,String fileName){
		  try{
			  OutputFormat format = new OutputFormat("	",true);
			  format.setEncoding(formatWay);
			  
			  BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(fileName)));
			  
			  XMLWriter xmlWriter = new XMLWriter(new PrintWriter(bos),format);
			  xmlWriter.write(doc);
			  xmlWriter.close();
		  }catch (IOException e) {
			e.printStackTrace();
		  }
	}
	/**
	 * 判断一个对象是否实现了某个特定的接口
	 * @param theClass Class
	 * @param theInterface String
	 * @return 实现了这个接口返回true
	 */
	public static boolean isRealizeInterface(Class theClass,String theInterface){
		Class<?>[] classes = theClass.getInterfaces();
		for(Class c : classes){
			if(c.getName().equals(theInterface)){
				return true;
			}
		}
		return false;
	}
	/**
	 * 获取给定obj的所有的变量和变量的名称
	 * @param obj
	 * @return Map<变量名,变量值>
	 */
	public static Map<String,String> getAttributeMap(Object obj) {
		if(obj == null || "".equals(obj)) return null;
		Map<String,String> attributeMap = new HashMap<String, String>();
		Field[] fields = obj.getClass().getDeclaredFields();
		for(Field field:fields){
			 // 对于每个属性,获取属性名
			String varName = field.getName();
			try{
				//获取原来的访问控制权限 
				boolean accessFlag = field.isAccessible();
				//修改之
				field.setAccessible(true);
				//获取对象field 中varName 属性的值
				Object value = field.get(obj); 
//				System.out.println("对象中包含的变量:" + varName +  " = " + value);
				//恢复访问权限
				field.setAccessible(accessFlag);
				attributeMap.put(varName, String.valueOf(value));//将任意可转换的类型转换为String
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
		return attributeMap;
	}
	
	/**
	 * 	获取xml文件的根节点
	 * @param xmlFileName
	 * @return xml文件的根节点
	 * @throws Throwableo
	 */
	public static Element getRootFromXml(String xmlFileName) throws Throwable{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File(xmlFileName));
		Element elementRoot = doc.getRootElement();//获取根元素
		return elementRoot;
	}
	
	/**
	 * 读取一个xml下的属性和节点的方法
	 * @throws Throwable
	 */
	public static Map<String,ElementAtt> readInfo(String fileName) throws Throwable{
		if(fileName == null || "".equals(fileName)){
			throw new FileNotFoundException("文件名不能为空"); 
		}
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File(fileName));
		Element elementRoot = doc.getRootElement();//获取根元素 最底层的元素
		
		Map<String,ElementAtt> rootMap = new HashMap<String, ElementAtt>();
		//迭代器:取根元素下的子元素名称
		Iterator<Element> iter = elementRoot.elementIterator();
		System.out.println("取根元素下的子元素名称");
		int eleBaseCount = 0;
		Element elebase = null;
		while(iter.hasNext()){
			elebase = iter.next();
			eleBaseCount++;
			String eleName  = elebase.getName();//获取元素名称
			String eleValue = elebase.attributeValue("class");//获取元素某项属性 这里指定为class属性
			System.out.println(eleName + "=" + eleValue);
			Map<String, String> eleMap = getInfo(elebase);
			//节点名字可能相同,比如都是student,加个count区别
			rootMap.put(eleName+eleBaseCount,new ElementAtt(eleValue,eleMap));//将一个节点包装起来,Map中每一项都是一个完整类的全部属性
		}
		return rootMap;
	}
	/**
	 * 通过一个root 获取所有的 递归调用
	 * 	并添加到map中
	 * @param root
	 */
	public static Map<String,String> getInfo(Element root){
		Map<String,String> infoMap = new HashMap<String, String>();//用来存贮所有当前节点的子属性以及子属性的map
		Iterator<Element> iter = root.elementIterator();//遍历root的element
		int childCount = 0;//用来指明子属性的map并计数
		while(iter.hasNext()){
			Element element = iter.next();
			String eleName = element.getName();//获取元素名称
			String eleValue = element.getText();//获取元素值
//			System.out.println(eleName + " " + eleValue);
			infoMap.put(eleName, eleValue);
			/** 对于有特殊属性的节点(将属性写成<student class="test" >)时要获取class会用到的操作 */
//			Iterator<Attribute> iter1 = element.attributeIterator();
//			System.out.println("获取属性名称、值");
//			while (iter1.hasNext()) {
//				Attribute elAtt = iter1.next();
//				String elAttName = elAtt.getName();
//				String elAttValue = elAtt.getValue();//获取属性名称和值
//				System.out.println(elAttName+" "+elAttValue);
//			}
			/** 没有实现,对于当前需求来说, 也没有什么用 目前只需要一层结构 
			 * (The method put(String, String) in the type Map<String,String> is not applicable for the arguments (String, Map<String,String>))
			 */
//			Map<String,String> childMap = getInfo(element);//自己调用自己 递归方法
//			if(childMap != null){
//				infoMap.put("child"+childCount, childMap);
//			}
		}
		return infoMap;
	}
	/**
	 * 从xml文件中读出内容并对其进行实例化,返回实例化之后的数组(该类必须存在才行)
	 * @throws Throwable
	 */
	public static Object[] getObjectFromXml(String fileName) throws Throwable{
		/** 从文件读取一个xml下的属性和节点的方法 */
		Map<String,ElementAtt> xmlMap = readInfo(fileName);
		Object[] objectFromXml = new Object[xmlMap.keySet().size()];
		int index = 0;
		for(String eleBase : xmlMap.keySet()){
			ElementAtt elementAtt = xmlMap.get(eleBase);
			String className = elementAtt.getEleValue();
			objectFromXml[index] = (Object) createObjectByMap(elementAtt.getEleMap(),Class.forName(className).newInstance());
			index++;
		}
		return objectFromXml;
	}
	/**
	 * 对一个对象中的各个属性进行赋值,值的来源来自于attributeMap
	 * @throws NoSuchFieldException 
	 * @throws SecurityException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	public static Object createObjectByMap(Map<String,String> aMap,Object aObj) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException{
//		Field[] fields = aObj.getClass().getDeclaredFields();
		for(String attName : aMap.keySet()){
			Field field = aObj.getClass().getDeclaredField(attName);
			//获取原来的访问控制权限 
			boolean accessFlag = field.isAccessible();
			//修改之
			field.setAccessible(true);
			//根据不同的类型注入值
			if(field.getType().getName().equals("int")){
				//System.out.println("如果是int类型");
				field.set(aObj, Integer.valueOf(aMap.get(attName)));
			}else{
				field.set(aObj, aMap.get(attName));
			}
			//恢复访问权限
			field.setAccessible(accessFlag);
		}
		return aObj;
	}
}

/**
 * 存贮base节点的相关属性 eleValue 包含了该节点标识的类名,eleMap是具体的属性
 * @author qihigh
 *
 */
class ElementAtt {
	public ElementAtt(String eleValue, Map<String, String> eleMap) {
		this.eleValue = eleValue;
		this.eleMap = eleMap;
	}
	private String eleValue;
	private Map<String, String> eleMap;
	
	public String getEleValue() {
		return eleValue;
	}
	public void setEleValue(String eleValue) {
		this.eleValue = eleValue;
	}
	public Map<String, String> getEleMap() {
		return eleMap;
	}
	public void setEleMap(Map<String, String> eleMap) {
		this.eleMap = eleMap;
	}
	@Override
	public String toString() {
		return "[eleValue = "+eleValue+" eleMap = "+eleMap+"]";
	}
	
	
}

/**
 * 数据持久化对象
 * @author qihigh
 *
 */

class Student{
	private String userName;
	private int age;
	private String sex;
	private String selfDescription;
	private String extend;
	
	public Student(){}
	public Student(String userName, int age, String sex, String selfDescription,String extend) {
		this.userName = userName;
		this.age = age;
		this.sex = sex;
		this.selfDescription = selfDescription;
		this.extend = extend;
	}
	
	public String getUserName() {
		return userName;
	}
	
	@Override
	public String toString(){
		return "[userName= "+userName+";age="+age+";sex="+sex+";selfDescription="+selfDescription+"]";
	}
}
分享到:
评论

相关推荐

    Tinyxml 源代码(VC6 & VS2005)

    TinyXML使用文档对象模型(DOM),这意味着XML数据被解析成一个可被浏览和操作的C++对象,然后它可以被写到磁盘或者另一个输出流中。你也可以把C++对象构造成一个XML文档然后把它写到磁盘或者另一个输出流中。 ...

    xml分页+ajax请求数据源+dom取结果实例代码

    单击[选择]时,根据当前选择(下拉框)的分类ID,使用ajax请求,取得数据源(服务端使用dataSet.getXml()输出,因为数据量不是很大,所以就偷懒了) 2.客户端使用xml数据岛分页显示(使用数据岛分页比较简单,不用写太多的代码)...

    hibernate核心包

    dom4j-1.6.1.jar dom4j XML 解析器 jta-1.1.jar 标准的 JAVA 事务处理接口 javassist-3.9.0.GA.jar 代码生成工具 (Hibernate用它在运行时扩展 Java类和实现,同cglib包) slf4j-api-1.5.8.jar和slf4j-log4j12-1.5.0....

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    8.4 jdbc数据源和连接池 299 8.5 mysql对中文的处理 302 8.6 小结 302 第9章 会话跟踪 303 9.1 用于会话跟踪的技术 303 9.1.1 ssl会话 304 9.1.2 cookies 304 9.1.3 url重写 305 9.2 java servlet api的会话...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    8.4 jdbc数据源和连接池 299 8.5 mysql对中文的处理 302 8.6 小结 302 第9章 会话跟踪 303 9.1 用于会话跟踪的技术 303 9.1.1 ssl会话 304 9.1.2 cookies 304 9.1.3 url重写 305 9.2 java servlet api的会话...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    8.4 jdbc数据源和连接池 299 8.5 mysql对中文的处理 302 8.6 小结 302 第9章 会话跟踪 303 9.1 用于会话跟踪的技术 303 9.1.1 ssl会话 304 9.1.2 cookies 304 9.1.3 url重写 305 9.2 java servlet api的会话...

    多种数据库操作示例

    DbHelper 操作SQL Server、Oracle、Access、Excel、CSV五种数据源+ Xml文件读写 编译环境:VS2008+Win7 数据源: SQL Server 2005,Oracle 10g,Access 2003,Excel 2003,CSV,Xml 功能: 查看所有数据:读取...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    8.4 jdbc数据源和连接池 299 8.5 mysql对中文的处理 302 8.6 小结 302 第9章 会话跟踪 303 9.1 用于会话跟踪的技术 303 9.1.1 ssl会话 304 9.1.2 cookies 304 9.1.3 url重写 305 9.2 java servlet api的会话...

    JAVA_API1.6文档(中文)

    javax.xml.crypto.dsig.dom javax.xml.crypto.dsig 包特定于 DOM 的类。 javax.xml.crypto.dsig.keyinfo 用来解析和处理 KeyInfo 元素和结构的类。 javax.xml.crypto.dsig.spec XML 数字签名的参数类。 javax.xml...

    springmvcdemo

    1. 解析xml:dom4j.jar 2. 解析json:json-lib.jar 3 URL Mapping: ControllerClassNameHandlerMapping 映射控制器 4 使用MultiActionController 5 所有service利用spring注入到controller中,利用注解 6 数据库连接...

    Ajax完全自学手册(源代码).rar

    Ajax完全自学手册PPT和源代码分来上传了,需要PPT的请自己在我的资源里面查找。 1.本书1~22章所附代码的运行环境 操作系统:Windows 2003、Windows XP Professional,或者Windows 2000 开发环境:Microsoft Visual ...

    精通qt4编程(源代码)

    \ 第8章 文件处理 蔡志明介绍了Qt的文件处理,包括基于流的文本文件和二进制文件处理,文件信息和目录操作,目录以及文件的变化监控,文件引擎的编写。 219 \ 第9章 网络 李立夏介绍了Qt的网络处理,包括编写常见的...

    精通Qt4编程(第二版)源代码

    在逐渐掌握Qt 4的过程中,我们萌发了编写一本关于Qt 4的书来帮助初学者入门的想法。最终,在电子工业出版社博文视点资讯有限公司的大力支持下,我们的想法终于得以付诸实施。 \关于Qt \Qt是挪威的Trolltech公司的...

    java api最新7.0

    javax.xml.crypto.dsig.dom javax.xml.crypto.dsig 包特定于 DOM 的类。 javax.xml.crypto.dsig.keyinfo 用来解析和处理 KeyInfo 元素和结构的类。 javax.xml.crypto.dsig.spec XML 数字签名的参数类。 javax.xml....

    Ajax完全自学手册PPT和源代码(ptt格式)

    Ajax完全自学手册PPT和源代码分来上传了,需要PPT的请自己在我的资源里面查找。 1.本书1~22章所附代码的运行环境 操作系统:Windows 2003、Windows XP Professional,或者Windows 2000 开发环境:Microsoft Visual ...

    JavaAPI1.6中文chm文档 part1

    javax.xml.crypto.dsig.dom javax.xml.crypto.dsig 包特定于 DOM 的类。 javax.xml.crypto.dsig.keyinfo 用来解析和处理 KeyInfo 元素和结构的类。 javax.xml.crypto.dsig.spec XML 数字签名的参数类。 javax.xml...

    [Java参考文档]

    javax.xml.crypto.dsig.dom javax.xml.crypto.dsig 包特定于 DOM 的类。 javax.xml.crypto.dsig.keyinfo 用来解析和处理 KeyInfo 元素和结构的类。 javax.xml.crypto.dsig.spec XML 数字签名的参数类。 javax.xml...

    JavaAPI中文chm文档 part2

    javax.xml.crypto.dsig.dom javax.xml.crypto.dsig 包特定于 DOM 的类。 javax.xml.crypto.dsig.keyinfo 用来解析和处理 KeyInfo 元素和结构的类。 javax.xml.crypto.dsig.spec XML 数字签名的参数类。 javax.xml...

Global site tag (gtag.js) - Google Analytics