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

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

    博客分类:
  • java
 
阅读更多
这个是以前写的简单例子,后来发现 xstream 的做法跟我想到一起去了,不过人家做的相当完善。简单的小的文件适合用xstream来操作(xstream的 osgi版本用的时候有些问题,在bundle相互调用的时候出错,换成jar版的就可以)。
代码留作纪念:
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数据源操作类,可以将一个对象组织到xml文件中,
 * 如: outputDocUTF8ToFile(CreateXmlBaseObjectArray(person),"test.xml");

 * 也可以将该xml中的内容读出来,并根据其中内容生成相应的对象,
 * 如: Object[] personFromXml = getObjectFromXml("test.xml");

 * @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+"]";
	}
}

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    dom4j实战(一)——使用dom4j从XML中读取数据源配置

    在读取XML数据源配置时,我们通常会遇到以下几个步骤: 1. **解析XML文件**:首先,需要加载XML文件并将其解析成DOM4J的Document对象。这可以通过`DocumentBuilder`类实现,通过`read()`方法读取XML文件内容。 2. ...

    dom4j 解析xml实例

    DOM4J作为一个解析器,可以将XML文档转换为一个可操作的Java对象模型,方便我们进行数据的读取和写入。 在`Dom4jTest1.java`中,程序通常会包含以下步骤: 1. 引入DOM4J库:首先,我们需要在Java源代码中引入DOM4J...

    dom4j解析XML文件格式

    DOM4j(Document Object Model for XML)是一款Java平台上的开源XML处理库,它提供了灵活、高效且易于使用的API来处理XML数据。DOM4j支持DOM、SAX、JAXP等多种XML解析方式,并内置了对XPath的支持,这使得开发人员...

    dom4j解析xml文件必备jar包

    DOM4J在Java社区中被广泛使用,尤其是在那些需要处理大量XML数据的应用中。这个压缩包包含了一些核心的DOM4J相关文件,以及必要的依赖库,以便于在项目中集成并使用DOM4J进行XML操作。 1. **dom4j.jar**:这是DOM4J...

    dom4j---xml解析jar包

    在Java环境中,解析XML文档时,我们通常会遇到各种库,其中DOM4J是一个非常流行的、功能强大的开放源代码库。这个库不仅简化了XML处理,还提供了XPath和XSLT的支持,使其成为Java开发者处理XML的首选工具之一。 **...

    DOM4J格式化XML

    但可以假设它是博文作者提供的补充材料,可能是为了帮助读者更好地理解XML处理背后的逻辑,通过UML(统一建模语言)来展示类图、序列图或其他图示,以便于解释DOM4J库中的类结构和操作流程。 综上所述,这篇关于...

    基于DOM4j和POI实现的XML文件转换为XLS(即标准EXCEL)的JAVA程序

    在该程序中,开发者首先会使用DOM4j解析XML文件,将XML数据结构转换为Java对象或数据结构。然后,利用Apache POI创建一个新的Excel工作簿,根据XML数据创建工作表、行和单元格,并填充相应的值。此外,可能还会涉及...

    dom4j源代码,包含dom4j.jar

    这个压缩包包含了DOM4J的源代码和预编译的jar文件,对于开发者来说,这是一个宝贵的资源,可以深入理解DOM4J的工作原理,并在实际项目中方便地使用它。 首先,DOM4J的核心概念是Element,它代表了XML文档中的一个...

    dom4j dom4j1.6 dom4j最新版

    在实际开发中,DOM4J常用于XML配置文件的读取、XML数据的交换、XML Web服务的客户端和服务端等场景。例如,在Spring框架中,DOM4J被用于解析配置文件,构建Bean的定义。通过理解并熟练使用DOM4J,开发者可以更高效地...

    Dom4j对xml文件做增删改查(使用分层思想)

    在IT行业中,XML(eXtensible Markup Language)是一种用于存储和传输数据的标记语言,因其结构化和可...在实际开发中,这样的设计模式能够帮助我们更好地管理复杂的应用程序,同时利用Dom4j的强大功能处理XML数据。

    dom4j-2.1.3.zip

    在实际开发中,DOM4J常用于读取XML配置文件、解析XML数据、生成XML报告等场景。例如,通过`Document`对象读取XML文件,然后使用`Element`和`XPath`来获取或修改数据。同时,DOM4J还提供了`Writer`接口,可以将XML...

    使用Fusion Charts制作报表(dom4j生成XML)

    这篇博客"使用Fusion Charts制作报表(dom4j生成XML)"主要介绍了如何利用Fusion Charts结合DOM4J库来生成XML数据,从而创建动态报表。 首先,我们需要理解Fusion Charts的核心概念。Fusion Charts提供了一系列预定...

    dom4j的Java工程

    在"dom4jdemo"这个子文件夹中,很可能是包含了一个或多个Java源代码文件,演示了如何使用DOM4J进行XML操作的实例。这些代码通常会包含导入DOM4J库的语句,如`import org.dom4j.Document;`和`import org.dom4j....

    dom4j源代码

    7. **集合框架集成**:DOM4J的API设计与Java集合框架紧密结合,使得XML数据可以方便地与Java对象相互转换。 8. **事件处理**:DOM4J允许注册事件处理器,可以监听XML解析过程中的特定事件,如开始解析、遇到元素、...

    dom4j 解析xml文件小例子

    1. 导入DOM4J库:首先,你需要在你的Java源代码中导入DOM4J相关的类,如`org.dom4j.Document`, `org.dom4j.DocumentHelper`, `org.dom4j.Element`等。 ```java import org.dom4j.Document; import org.dom4j....

    使用dom4j高效率xml解析,内涵demo程序,idea导入即可运行,适用于各种复杂xml的解析,给自己留作备份,有需要可下载。

    XML(eXtensible Markup Language)是一种用于标记数据的语言,广泛应用于配置文件、数据交换、文档存储等...在实际开发中,根据具体场景选择合适的方法,结合DOM4J提供的工具类,可以大大提高XML处理的效率和便捷性。

    dom4j读写xml文件

    在Java领域,XML常用于数据交换、配置文件以及存储结构化数据,因此理解和掌握如何使用dom4j对XML文件进行操作是至关重要的。 DOM(Document Object Model)是一种用于表示XML文档的树形结构,而dom4j是基于Java的...

    dom4j.jar 下载

    4. **使用**:在你的代码中导入DOM4J的类,如`org.dom4j.Document`、`org.dom4j.Element`等,然后使用提供的API进行XML操作。 DOM4J的核心功能包括: - **解析XML**:DOM4J支持SAX和DOM解析方式,可以根据需求选择...

    dom4j所需要的包和依赖包

    - **SAXReader**:用于解析XML文档,将XML数据转换为DOM4J的Document对象。 - **XMLWriter**:将DOM4J的Document对象写回XML文件,提供格式化的输出。 - **XPath**:基于XPath表达式进行查询,可以快速定位XML...

    dom4j解析xml

    ### DOM4J解析XML知识点详解 #### 一、DOM4J简介 DOM4J(Document Object Model for Java)是一个开源的Java库,用于处理XML文档。...通过理解其核心概念和使用流程,可以有效地在各种项目中应用DOM4J进行XML操作。

Global site tag (gtag.js) - Google Analytics