`
mengqingyu
  • 浏览: 328564 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

dom4j+反射,面向对象方式的xml格式转换

阅读更多
工作中遇到了两种不同表单设计器保存xml之间的相互转换需求,在此做个记录,利用dom4j+反射的面向对象方式实现的,其中因为需求原因有部分定制代码,不过稍作修改可以改成通用的文件转换功能。实体bean在此省略。。。


package com.test.xml.main;

public interface IConvertXml {
	
	/**
	 * 
	 * @function:读xml
	 * @param obj  需要存储的对象
	 * @param filePath   xml文件路径
	 * @return
	 * @throws Exception
	 * @author: mengqingyu    2012-8-27 下午02:06:21
	 */
	Object readXml(Object obj, String filePath) throws Exception;
	
	/**
	 * 
	 * @function:
	 * @param obj    需要输出到xml中的对象
	 * @param filePath   xml文件路径
	 * @throws Exception
	 * @author: mengqingyu    2012-8-27 下午02:07:00
	 */
	void writeXml(Object obj, String filePath) throws Exception;
}

package com.test.xml.main;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.dom4j.Attribute;
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;

/**
 * 
 * 类功能描述:2种不同规范格式的xml之间的转换
 *
 * @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
 * @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp  $
 * Create:  2012-9-3 下午01:39:16
 */
public class ConvertXml implements IConvertXml{
	
	private final String packagePath = "com.test.xml.bean";
	
	private Map<String,String> fieldMap = new HashMap<String,String>();
	
	private Map<String,String> itemMap = new HashMap<String,String>();
	
	public ConvertXml() {
		super();
		initMap();
	}

	public Object readXml(Object obj, String filePath) throws Exception {
		SAXReader reader = new SAXReader();
        Document  document = reader.read(new File(filePath.toString().replace("file:/", "")));
        
        Element rootElm = document.getRootElement();
        initBean(obj, rootElm, false);
        
        List<Element> elements = rootElm.selectNodes("elements/band/frame/*");
        for(Element element:elements){
        	String className = getClassName(element.getName());
        	if(className==null)continue;
        	String classPath = packagePath+"."+className;
        	Object subObj = Class.forName(classPath).newInstance();
        	for(Iterator it=element.elementIterator();it.hasNext();){
        		Element elementSub = (Element)it.next();
        		initBean(subObj, elementSub, true);
        	}
            Field[] field = obj.getClass().getDeclaredFields();
            for (int i=0;i<field.length;i++){  
	            if (field[i].getName().equalsIgnoreCase(className+"s")){ 
	            	Set<Object> items = (Set<Object>)this.getField(field[i], obj);
	            	items.add(subObj);
            	}   
            } 
        }
        return obj;
	}
	
	public void writeXml(Object obj, String filePath) throws IllegalArgumentException, IllegalAccessException, IOException {
		Document document = DocumentHelper.createDocument();
		Element root = document.addElement("form");//根节点
		
        Field[] field = obj.getClass().getDeclaredFields();    
        for (int i=0;i<field.length;i++){
        	if("interface java.util.Set".equals(field[i].getType().toString())){
        		Set<Object> items = (Set<Object>)this.getField(field[i], obj);
        		for(Object o:items){
        			Element element = root.addElement("item");
        			Field[] fieldSub = o.getClass().getDeclaredFields(); 
        	        for (int j=0;j<fieldSub.length;j++){
        	        	element.addAttribute(fieldSub[j].getName(), (String)this.getField(fieldSub[j], o));
        	        }
        		}
        	}
        	else{
        		root.addAttribute(field[i].getName(), (String)this.getField(field[i], obj));
        	}
        }
        root.addElement("heji").addAttribute("value", "");
        root.addElement("shenhe").addAttribute("value", "");
        
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("GBK");   // 设置XML文件的编码格式
        XMLWriter writer = new XMLWriter(new FileOutputStream(filePath.toString().replace("file:/", "")), format);   
        writer.setEscapeText(false);
        writer.write(document);  
        writer.flush(); 
        writer.close(); 
	}
	
	/**
	 * 
	 * @function:初始化map 这里存放了两个xml属性映射关系
	 * @author: mengqingyu    2012-8-27 下午02:05:58
	 */
	private void initMap() {
		//目标文件的属性名和源文件的属性名映射
		fieldMap.put("name", "title");
		fieldMap.put("canvasWidth", "formwidth");
		fieldMap.put("canvasHeight", "formheight");
		fieldMap.put("key", "i_id");
		fieldMap.put("x", "i_x");
		fieldMap.put("y", "i_y");
		fieldMap.put("width", "i_width");
		fieldMap.put("height", "i_height");
		fieldMap.put("columnName", "i_code");
		fieldMap.put("columnLen", "i_length");
		fieldMap.put("keyname", "i_value");
		fieldMap.put("value", "i_value");
		fieldMap.put("fontName", "i_style");
		fieldMap.put("fontSize", "i_style");
		fieldMap.put("textAlignment", "i_style");
		fieldMap.put("size", "i_style");
		fieldMap.put("readOnly", "i_readonly");
		fieldMap.put("maxlength", "i_length");
		fieldMap.put("tabIndex", "i_tabseq");
		fieldMap.put("dataType", "i_type");
		
		//源文件的标签名和实体bean类名的映射
		itemMap.put("label", "Label");
		itemMap.put("line", "Line");
		itemMap.put("textfield", "Textfield");
		itemMap.put("checkbox", "Checkbox");
	}
	
	/**
	 * 
	 * @function:通过xml中的内容初始化bean
	 * @param obj  要初始化的bean
	 * @param element   文档元素
	 * @param flag  是否递归解析子节点
	 * @throws Exception
	 * @author: mengqingyu    2012-8-27 下午02:05:10
	 */
	private void initBean(Object obj,Element element, boolean flag) throws Exception{
		for(Iterator it=element.attributeIterator();it.hasNext();){//遍历当前节点的所有属性
			Attribute attribute = (Attribute) it.next();
			Field[] field = obj.getClass().getDeclaredFields();
			for (int i=0;i<field.length;i++){  //根据xml内容赋值到对象中,使用对象中默认值不需要重新赋值
				if (field[i].getName().equals(getfieldValue(attribute.getName()))){
					this.customAttribute(field[i], element, attribute, obj);//一些定制处理
					this.invokeMethod(this.setMethodName(field[i].getName()), obj, attribute.getText());
				}   
			} 
		}
		if(flag==true){//递归子节点
			List<Element> subElements = element.elements();
			for(Element subElement:subElements){
				this.initBean(obj, subElement, true);
			}
		}
	}
	
	/**
	 * 
	 * @function:这里添加了一些非规则的定制内容转换
	 * @param field 类的属性
	 * @param element 文档标签对象
	 * @param attribute 标签里的属性
	 * @param obj 属性所属类对象
	 * @throws IllegalArgumentException
	 * @throws SecurityException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 * @author: mengqingyu    2012-8-29 上午10:31:47
	 */
	private void customAttribute(Field field, Element element, Attribute attribute, Object obj) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		if("text".equals(element.getName())){
			if("keyname".equals(attribute.getName())){
				if(element.getText().indexOf("javascript")==-1){
					attribute.setText(element.getText().replace("\n", "<br/>"));
				}
				else{
					attribute.setText("<a href=\"#\">此处添加事件</a>");
				}
			}
		}
		else if("i_style".equals(field.getName())){
			String value = (String)this.invokeMethod(this.getMethodName(field.getName()),obj);
			if("fontName".equals(attribute.getName())){
				attribute.setText(value.replace("宋体", attribute.getText()));
			}
			else if("size".equals(attribute.getName())||"fontSize".equals(attribute.getName())){
				attribute.setText(value.replace("12", attribute.getText()));
			}
			else if("textAlignment".equals(attribute.getName())){
				attribute.setText(value.replace("left", attribute.getText().toLowerCase()));
			}
		}
		else if("databaseElement".equals(element.getName())){
			if("dataType".equals(attribute.getName())&&"varchar".equals(attribute.getValue())){
				attribute.setText("textfield");
				this.invokeMethod(this.setMethodName("i_data_type"), obj, "字符");
			}
			else if("dataType".equals(attribute.getName())&&"decimal".equals(attribute.getValue())){
				attribute.setText("numberfield");
				this.invokeMethod(this.setMethodName("i_data_type"), obj, "数值");
			}
		}
	}
	/**
	 * 
	 * @function:执行方法
	 * @param methodName 方法名
	 * @param object 方法所在对象
	 * @param value  方法中的参数值
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @author: mengqingyu    2012-8-27 下午02:03:51
	 */
	private void invokeMethod(String methodName, Object object,Object value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {   
		Method method = object.getClass().getMethod(methodName,String.class);
		method.invoke(object,value);
	} 
	
	/**
	 * 
	 * @function:执行方法
	 * @param methodName 方法名
	 * @param object 方法所在对象
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @author: mengqingyu    2012-8-28 下午04:27:38
	 */
	private Object invokeMethod(String methodName, Object object) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {   
		Method method = object.getClass().getMethod(methodName);
		return method.invoke(object);
	} 
	
	/**
	 * 
	 * @function:获得属性值
	 * @param field   属性对象
	 * @param object  属性所属类对象
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @author: mengqingyu    2012-8-27 下午02:03:40
	 */
	private Object getField(Field field,Object object) throws IllegalArgumentException, IllegalAccessException {   
		field.setAccessible(true);//设置属性可以修改   
		return field.get(object);
	} 
	
	/**
	 * 
	 * @function:通过属性生成get方法名
	 * @param str
	 * @return
	 * @author: mengqingyu    2012-8-27 下午02:03:27
	 */
	private String getMethodName(String str){   
		return "get"+ firstToUpperCase(str);   
	}   
	
	/**
	 * 
	 * @function:通过属性生成set方法名
	 * @param str
	 * @return
	 * @author: mengqingyu    2012-8-27 下午02:03:27
	 */
	private String setMethodName(String str){   
		return "set"+ firstToUpperCase(str);   
	}   
	
	/**
	 * 首字母大写
	 */
	private String firstToUpperCase(String str){   
		return Character.toUpperCase(str.charAt(0)) + str.substring(1);   
	}
	
	/**
	 * 
	 * @function:获得两组xml标签中属性的对应关系
	 * @param key
	 * @return
	 * @author: mengqingyu    2012-8-27 下午02:02:48
	 */
	private String getfieldValue(String key){
		return fieldMap.get(key);
	}
	
	/**
	 * 
	 * @function:获得标签与类的关系
	 * @param key
	 * @return
	 * @author: mengqingyu    2012-8-27 下午02:02:23
	 */
	private String getClassName(String key){
		return itemMap.get(key);
	}
}

package com.test.xml.main;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import org.dom4j.DocumentException;

import com.test.xml.bean.FormFlow;

public class MainXml {

	/**
	 * @function:
	 * @param args
	 * @author: mengqingyu    2012-5-2 下午04:56:17
	 * @throws DocumentException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws ClassNotFoundException 
	 * @throws IOException 
	 */
	public static void main(String[] args) throws Exception {
		IConvertXml convertXml = new ConvertXml();
		FormFlow form = (FormFlow)convertXml.readXml(new FormFlow(),MainXml.class.getResource("/")+"xt.xml");
		convertXml.writeXml(form, MainXml.class.getResource("/")+"xt_new.xml");
	}
}
分享到:
评论

相关推荐

    基于Java的XML解析与反射设计模式.doc

    java作为现下最流行的可撰写的跨平台应用软件的面向对象的程序设计语言,在多系统 数据交互这方面具有先天的优势。它具有动态性,它的设计目标之一是适应于动态变化 的环境。java程序需要的类能够动态的被载入到...

    JavaScript王者归来part.1 总数2

     7.2.3 反射机制--枚举对象属性   7.3 对象的构造   7.3.1 构造函数--一个双精度浮点数封装类的例子   7.3.2 缺省构造和拷贝构造   7.3.3 对象常量   7.4 对象的销毁和存储单元的回收   7.5 JavaScript...

    .NET机试题目(全)

    .NET机试题目包括.Net概述、数据类型、运算符、表达式和数据类型转换、枚举 结构、程序控制语句、面向对象编程、委托、事件、数组、集合、 泛型、反射、异常、文件操作、流、XML的处理、ADO.NET、ADO.NET、JS数据...

    Visual.Basic.2010.&.NET4.高级编程(第6版)-文字版.pdf

    2.1 面向对象的术语 64 2.1.1 对象、类和实例 64 2.1.2 对象的组成 65 2.1.3 system.object 68 2.2 使用visual basic类型 68 2.2.1 值类型和引用类型 69 2.2.2 基本类型 71 2.3 命令:条件语句 72 ...

    Java JDK实例宝典

    第1章 Java基础 1.1 转换基本数据类型 1.2 Java的运算符 1.3 控制程序的流程 1.4 计算阶乘 1.5 实现命令行程序 第2章 Java面向对象程序设计 2. 1 复数类 2. 2 equals.chashCode...

    PHP和MySQL WEB开发(第4版)

    6.1 理解面向对象的概念 6.1.1 类和对象 6.1.2 多态性 6.1.3 继承 6.2 在PHP中创建类、属性和操作 6.2.1 类的结构 6.2.2 构造函数 6.2.3 析构函数 6.3 类的实例化 6.4 使用类的属性 6.5 使用private和public关键字...

Global site tag (gtag.js) - Google Analytics