1. 程式人生 > >java反射與xml檔案解析

java反射與xml檔案解析

    在專案開發的過程中,遇到了要將日誌匯出為xml格式和將xml匯入到日誌資料庫中的功能需求,因為專案中存在多種日誌形式(這聽起來很奇葩是不是?),我實在懶得為每一種日誌都寫一個方法。想到在開始的設計過程中,將每種的日誌都對映為一個pojo,故想到了java的反射機制,也是個好方法,下面的程式碼只是簡單地單元測試了下,不能保證正確,緊供參考。

package com.netauth.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netauth.constants.Constant;
import com.netauth.orm.OrmUtil;
import com.netauth.pojo.User;

public class XmlUtil {

	private static Logger logger = LoggerFactory.getLogger(XmlUtil.class);

	/**
	 * 根據所傳入的pojo物件列表生成xml檔案
	 * 
	 * @author song @time 2014年7月15日-上午10:07:45
	 * @param outputPath
	 *            輸出的資料夾路徑,指定為 System.getProperty("user.dir")+"/logs"
	 * @param objects
	 *            (pojo)物件列表,第一個屬性為id
	 * @return
	 */
	public static <T> boolean generateXml(String outputPath, List<T> objects) {

		if ("".equals(outputPath) || null == outputPath) {
			logger.debug("指定的目標資料夾為空");
			return false;
		}
		if (null == objects || 0 == objects.size()) {
			logger.debug("所傳的pojo物件列表為空");
			return false;
		}

		String pojoName = objects.get(0).getClass().getSimpleName();
		String rootName = pojoName + "s";

		Element root = new Element(rootName);
		Document doc = new Document(root);
		// 得到當前pojo的執行時的型別
		Class c = objects.get(0).getClass();
		// 得到該類的所有屬性名稱
		Field[] fields = c.getDeclaredFields();

		if (fields.length == 0) {
			logger.debug("當前實體的屬性個數為0");
			return false;
		}
		if (!"id".equals(fields[0].getName())) {
			logger.debug("當前實體的第一個屬性名稱不為id");
			return false;
		}

		for (int i = 0; i < objects.size(); i++) {

			Object o = objects.get(i);
			// 為節點新增‘id’ 屬性
			Element elements = new Element(pojoName);
			elements.setAttribute("id", OrmUtil.getValue(fields[i], o).toString());

			// 為節點新增子子節點
			for (int index = 1; index < fields.length; index++) {

				Element element = new Element(fields[index].getName());
				element.setText(OrmUtil.getValue(fields[index], o).toString());
				elements.addContent(element);
			}

			root.addContent(elements);
		}
		// 設定xml輸出格式
		Format format = Format.getPrettyFormat();
		format.setIndent("  ");
		format.setEncoding("UTF-8");

		XMLOutputter outputter = new XMLOutputter(format);
		try {
			// 建立輸出資料夾
			File xmlDir = new File(outputPath);
			if (xmlDir.exists()) {
				logger.debug("路徑存在:" + outputPath);
			} else {
				xmlDir.mkdirs();
			}
			// 建立輸出檔案
			Date date = new Date();
			DateFormat f = new SimpleDateFormat("yyMMddhhmmss.S", Locale.US);
			String dataStr = f.format(date);
			File xml = new File(outputPath + "/xml_" + dataStr);
			try {
				xml.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			outputter.output(doc, new FileOutputStream(xml));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}

	public static List<Object> paraseXml(File xmlFile, String basePacketName) {

		// 返回構造好的pojo物件列表
		List<Object> pojos = new ArrayList<Object>();

		SAXBuilder builder = new SAXBuilder(false);
		Document document = null;
		try {
			document = builder.build(xmlFile);
			Element root = document.getRootElement();
			String rootString = root.getName().toString();
			String ObjectName = rootString
					.substring(0, rootString.length() - 1);

			// 儲存xml檔案中的物件元素
			List<Object> resultList = new ArrayList<Object>();
			try {
				Object object = null;
				Class clazz = null;
				List<String> proName = new ArrayList<String>();
				List<Object> proVal = new ArrayList<Object>();
				try {
					// 得到型別
					clazz = Class.forName(basePacketName + ObjectName);

					// 得到所有的 物件元素 列表
					resultList = root.getChildren(ObjectName);
					// 迭代每隔物件元素
					for (Iterator iterator = resultList.iterator(); iterator
							.hasNext();) {
						Element tempObect = (Element) iterator.next();
						Integer id = Integer.valueOf(tempObect
								.getAttributeValue("id"));

						// 新增第一個id屬性的名稱-值
						proName.add("id");
						proVal.add(id);
						// 取出其它屬性的值
						List<Element> childs = tempObect.getChildren();
						Iterator<Element> it = childs.iterator();
						while (it.hasNext()) {
							Element tempField = (Element) it.next();
							proName.add(tempField.getName());
							proVal.add(tempField.getTextNormalize());
						}
						//建立具體例項
						object = clazz.newInstance();
						OrmUtil.setProperties(proName, proVal, object);
						pojos.add(object);

					}
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return pojos;
	}

	public static void main(String[] args) {
		User user = new User();
		user.setId(1);
		user.setName("a");
		user.setPassword("aaaa");

		List<User> list = new ArrayList<User>();
		list.add(user);
		// generateXml(System.getProperty("user.dir") + "/logs", list);

		File file = new File(
				"D:\\Net\\workspace\\net_auth2\\logs\\xml_140715104606.1");
		List<Object> list2=paraseXml(file, Constant.POJO_BASE_PACKET_NAME);
		
		for (Iterator iterator = list2.iterator(); iterator.hasNext();) {
			Object object = (Object) iterator.next();
			if(object instanceof User){
				System.out.println(object.toString());
			}
		}
	}

}


   下面是OrmUtil工具類中設計的方法:

  /**
     * 得到表的主鍵
     * 
     * @author felix  @date 2014-3-19 下午1:53:44
     * @param clazz
     * @return
     */
    public static Field getIdField(Class<?> clazz){
    	try {
			return clazz.getDeclaredField("id");
		} catch (Exception e) {
			logger.error(" no id field \t " + clazz ,e);
			throw new IllegalArgumentException(" no id field \t " + clazz);
		}
    }
    
    /**設定一個物件的所有屬性值
     *@author song @time 2014年7月15日-下午12:47:31
     *@param proName
     *@param proVal
     *@param o
     */
    public static void setProperties(List<String> proName,
			List<Object> proVal, Object o) {

		Class clazz = o.getClass();
		for (int index = 0; index < proName.size(); index++) {
			try {
				Field field = clazz.getDeclaredField(proName.get(index));
				Method method = clazz.getDeclaredMethod(
						getSetterName(field.getName()),
						new Class[] { field.getType() });
				method.invoke(o, proVal.get(index));
			} catch (Exception e) {
				logger.error(" set properties failed \t " + clazz ,e);
			}
		}
	}
    
    /**設定一個物件的單個屬性值
     *@author song @time 2014年7月15日-下午12:49:59
     *@param proName
     *@param proVal
     *@param o
     */
    public static void setProperty(String proName,Object proVal,Object o){
    	
    	Class clazz=o.getClass();
    	try {
			Field field = clazz.getDeclaredField(proName);
			Method method = clazz.getDeclaredMethod(
					getSetterName(field.getName()),
					new Class[] { field.getType() });
			method.invoke(o, proVal);
		} catch (Exception e) {
			logger.error(" set properties failed \t " + clazz ,e);
		}
    }
    /**得到set方法
     *@author song @time 2014年7月15日-下午12:44:03
     *@param propertyName
     *@return
     */
    private static String getSetterName(String propertyName) {
		String method = "set" + propertyName.substring(0, 1).toUpperCase()  
                + propertyName.substring(1);  
        return method; 
	}
    
    /**得到get方法
     *@author song @time 2014年7月15日-下午12:44:46
     *@param propertyName
     *@return
     */
    public static String getGetterName(String propertyName) {  
        String method = "get" + propertyName.substring(0, 1).toUpperCase()  
                + propertyName.substring(1);  
        return method;  
    }  
    
  下面是main的xml檔案內容:
<?xml version="1.0" encoding="UTF-8"?>
<Users>
  <User id="1">
    <name>a</name>
    <password>aaaa</password>
  </User>
  <User id="2">
    <name>b</name>
    <password>bbbb</password>
  </User>
</Users>


   不多說了,程式碼可能很渣,見笑見笑.

相關推薦

java反射xml檔案解析

    在專案開發的過程中,遇到了要將日誌匯出為xml格式和將xml匯入到日誌資料庫中的功能需求,因為專案中存在多種日誌形式(這聽起來很奇葩是不是?),我實在懶得為每一種日誌都寫一個方法。想到在開始的設計過程中,將每種的日誌都對映為一個pojo,故想到了java的反射機制,

Java眼中的XML---檔案讀取(二)SAX解析XML檔案

目錄 (一)SAX解析是什麼? (二)SAX解析和DOM解析的區別? (三)SAX方法解析XML的步驟 (四)SAX解析Java程式碼實現 (一)SAX解析是什麼? SAX(simple API for XML)是一種XML解析的

Java眼中的XML---檔案讀取(一)DOM解析XML檔案

目錄 (一)什麼是XML? (二)XML的作用 (三)DOM解析XML檔案的準備工作 (四)使用DOM解析XML檔案的屬性名和屬性值 (五)使用DOM解析XML檔案的節點名和節點值 (一)什麼是XML? XML 指可

JAVA以及JSP中讀取XML檔案(解析及路徑問題)

    在系統開發過程中,從配置檔案中讀取配置資訊是每一個系統必須具備的功能,例如,我們要配置讀取資料庫配置資訊,包括驅動程式名、連線字串,使用者名稱,口令等資訊,由於這些資訊會隨著使用者的不同而發生

Java中讀取XML檔案,生成XML格式的字串並解析這個字串

由於最近要用的是XML格式的字串,而不用寫到檔案中,所以對原始程式碼進行了修改如下: 要讀的xml檔案 <?xml version="1.0" encoding="GB2312"?> <學生花名冊> <學生 性別 = "男">

Java中讀取xml檔案---SAX解析

SAX方式解析xml步驟 1、通過SAXParserFactory的靜態newInstance()方法獲取SAXParserFactory例項factory 2、通過SAXParserFactory例項的newSAXParser()方法返回SAXPa

Java中對xml檔案的四種解析方式

books.xml <?xml version="1.0" encoding="utf-8"?> <bookstore> <book id="1"> <name>冰與火之歌</name>

JAVA beanXML互轉的利器---XStream

pub 普通 ati mat his cit true 是我 package 最近在項目中遇到了JAVA bean 和XML互轉的需求, 本來準備循規蹈矩使用dom4j忽然想起來之前曾接觸過的XStream, 一番研究豁然開朗,利器啊利器, 下來就XStream的一些用法與

java反射動態代理的理解

system 對象的訪問 讓我 integer 打破 類屬性 全部 列表 ces 一、什麽是反射機制?   反射的官方定義是這樣的:在運行狀態中,對於任意的一個類,都能夠知道這個類的所有屬性和方法,對任意一個對象都能夠通過反射機制調用一個類的任意方法,這種動態獲取類信息及動

java反射獲取xml元素

java反射獲取xml元素類名: class Person { public void run(String who){ System.out.println("Person::run()" + who); } public void jump(String who)

java物件XML互轉

1. 定義XML對應的java實體類(可巢狀) import java.io.Serializable; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorT

MemoryModule閱讀PE檔案解析(一)

參考連結 https://github.com/fancycode/MemoryModule 本文閱讀github 上MemoryModule 程式碼的同時,介紹PE 檔案相關的基礎知識。       該專案實現“手

淺析java反射(位元組碼檔案)

什麼是反射? 先談談java程式的執行步驟吧! 先編譯後執行對嗎? 其實你想一想, 你寫的java程式碼機器真的能認識嗎? 早在以前就聽過了吧機器是隻認識0和1的 所以編譯這一階段也就是將java檔案編譯成位元組碼檔案也就是.class檔案 也就是01碼 那什麼又是反射呢?

JAVA反射 Android藍芽反射

  要想理解反射的原理,首先要了解什麼是型別資訊。Java讓我們在執行時識別物件和類的資訊,主要有2種方式:一種是傳統的RTTI,它假定我們在編譯時已經知道了所有的型別資訊;另一種是反射機制,它允許我們在執行時發現和使用類的資訊。 1、Class物件   理解RTTI在Java中的工作原

Java基礎之XML(SAX解析)

程式碼如下: package com.briup.SAXXML; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java

Java基礎之XML(DOM解析和建立)

程式碼如下: package com.briup.DOMXML; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java

[ java 工具類] xml字串解析成Map(DOM解析)

package com.tencent.jungle.wechat.util; import com.google.inject.Singleton; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeL

java json 轉為xml檔案

1.jar包引用 <dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> <versio

Android7.1 [Camera] cam_board.xml 檔案解析原始碼分析(一)

        原始碼平臺:rk3399           RK支援了很多個攝像頭,在驅動目錄hardware/rockchip/camer

Java之讀取XML檔案內容

下面是我的Persons.xml檔案內容: <?xml version="1.0" encoding="utf-8"?> <persons> <person id="0