根据xml模板 使用dom4j和java反射机制实现xml object 转换。
直接上代码:
接口
package logUtil;
/**
* @author lixiangokay
* xml object转换接口
*/
public interface XmlObjectTransform {
/**
* xml转换为对象
* @param templatePath
* @param inputXml
* @return
* @throws Exception
*/
public Object xmlToObject(String templatePath,String inputXml) throws Exception;
/**
* 对象转换为xml
* @param templatePath
* @param obj
* @param encoding
* @return
* @throws Exception
*/
public String objectToXml(String templatePath,Object obj,String encoding) throws Exception;
}
实现类
package logUtil;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.ibatis.common.beans.ClassInfo;
/**
* xml object 转换类
* @author lixiangokay
*
*/
public class XmlObjectTransformImpl implements XmlObjectTransform {
//模板节点属性名称
private static String ATTRIBUTE_OBJECTTYPE = "ObjectType";
private static String ATTRIBUTE_ISARRAY = "isArray";
private static String ATTRIBUTE_ATTRIBUTE = "Attribute";
private static String ATTRIBUTE_DATATYPE = "DataType";
/**
* xml转换为对象
* @param templatePath
* @param inputXml
* @return
* @throws Exception
*/
@Override
public Object xmlToObject(String templatePath, String inputXml)
throws Exception {
//xml解析后返回object
Object object = null;
//将传入的xml转换为Document
Document inputDocument = DocumentHelper.parseText(inputXml);
//获取xml解析模板
SAXReader saxReader = new SAXReader();
Document templateDocument = saxReader.read(Thread.currentThread().getContextClassLoader().getResourceAsStream(templatePath));
//获取xml中唯一与模板根节点对应的节点
Element templateRoot = templateDocument.getRootElement();
Element inputElement = inputDocument.getRootElement();
List<Element> elements = new LinkedList<Element>();
elements.add(inputElement);
//根据解析模板对xml进行解析并返回数据对象
object = getAnalyticalObject(templateRoot,getElementByName(elements,templateRoot.getName()),new Object(),true);
return object;
}
/**
* 对象转换为xml
* @param templatePath
* @param obj
* @param encoding
* @return
* @throws Exception
*/
@Override
public String objectToXml(String templatePath, Object obj, String encoding)
throws Exception {
String outputXml = null;
Document outputDocument = DocumentHelper.createDocument();
outputDocument.setXMLEncoding(encoding);
SAXReader saxReader = new SAXReader();
Thread.currentThread().getContextClassLoader();
Document templateDocument = saxReader.read(ClassLoader.getSystemResourceAsStream(templatePath));
//获取模板根节点
Element templateRoot = templateDocument.getRootElement();
//生成返回XML根节点
Element outputRoot = outputDocument.addElement(templateRoot.getName());
//以outputRoot的引用作为形参,getAnalyticalXml方法执行完毕后outputDocument就是最终返回的xml
getAnalyticalXml(templateRoot,outputRoot,obj,true);
outputXml = outputDocument.asXML();
return outputXml;
}
/**
* @param templateElement xml模板节点
* @param inputParentElement 请求xml节点
* @param object 返回的对象
* @param isTemplateRoot 是否是根节点
* @return
* @throws Exception
*/
private Object getAnalyticalObject( Element templateElement,Element inputParentElement,Object object,boolean isTemplateRoot) throws Exception{
try{
//非终端节点
if(templateElement.elements().size() != 0){
//非终端节点代表对象,需根据ObjectType通过反射实例化,并根据isArray属性决定实例化为对象数组还是单一对象
if(null != templateElement.attributeValue(ATTRIBUTE_OBJECTTYPE) &&
null != templateElement.attributeValue(ATTRIBUTE_ISARRAY)){
Class<?> templateElementClass = Class.forName(templateElement.attributeValue(ATTRIBUTE_OBJECTTYPE));
//对象数组节点
if( "true".equals(templateElement.attributeValue(ATTRIBUTE_ISARRAY))){
if(null != templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE)){
LinkedList<Object> templateElementLinkedList = new LinkedList<Object>();
Object[] templateElementObjectArray = null;
//获取传入的请求处理XML包含的当前解析节点的数量,即当前解析节点代表的对象的个数,并循环处理
for(Iterator<?> inputElementIterator = inputParentElement.elementIterator(templateElement.getName());
inputElementIterator.hasNext();){
Element inputElement = (Element) inputElementIterator.next();
Object templateElementObject = templateElementClass.newInstance();
//循环处理非终端节点下子节点,即循环处理当前解析节点代表的对象的属性
for(Iterator<?> templateElementIterator = templateElement.elementIterator();
templateElementIterator.hasNext();){
Element templateChildElement = (Element) templateElementIterator.next();
//递归处理各节点
getAnalyticalObject(templateChildElement,inputElement,templateElementObject,false);
}
templateElementLinkedList.add(templateElementObject);
}
//通过反射构建对象类型数组
if(null != templateElementLinkedList && templateElementLinkedList.size() > 0){
templateElementObjectArray = (Object[]) Array.newInstance(templateElementClass, templateElementLinkedList.size());
templateElementLinkedList.toArray(templateElementObjectArray);
}else{
System.out.println("注意:请求报文中不存在请求解析模板中的<"+templateElement.getName()+">节点");
}
//对象属性赋值
setValueByProperty(object,templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE),templateElementObjectArray);
}else{
throw new Exception("解析模板中非终端节点<"+templateElement.getName()+">的Attribute属性缺失");
}
}
//非对象数组节点
else{
//判断是否为解析模板根节点
if(isTemplateRoot){
if(null != inputParentElement){
object = templateElementClass.newInstance();
//循环处理非终端节点下子节点,即循环处理当前解析节点代表的对象的属性
for(Iterator<?> templateElementIterator = templateElement.elementIterator();templateElementIterator.hasNext();){
Element templateChildElement = (Element) templateElementIterator.next();
//递归处理各节点
getAnalyticalObject(templateChildElement,inputParentElement,object,false);
}
}else{
System.out.println("注意:请求报文中不存在请求解析模板中的<"+templateElement.getName()+">节点");
return null;
}
}else{
if(null != templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE)){
Object templateElementObject = templateElementClass.newInstance();
//获取传入的请求处理XML中与当前解析节点对饮的节点
Element inputElement = inputParentElement.element(templateElement.getName());
if(null != inputElement){
//循环处理非终端节点下子节点,即循环处理当前解析节点代表的对象的属性
for(Iterator<?> templateElementIterator = templateElement.elementIterator();templateElementIterator.hasNext();){
Element templateChildElement = (Element) templateElementIterator.next();
//递归处理各节点
getAnalyticalObject(templateChildElement,inputElement,templateElementObject,false);
}
}else{
System.out.println("注意:请求报文中不存在请求解析模板中的<"+templateElement.getName()+">节点");
}
//对象属性赋值
setValueByProperty(object,templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE),templateElementObject);
}else{
throw new Exception("解析模板中非终端节点<"+templateElement.getName()+">的Attribute属性缺失");
}
}
}
}
}
//终端节点
else{
if(null != templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE) && null != templateElement.attributeValue(ATTRIBUTE_DATATYPE)){
Element inputElement = inputParentElement.element(templateElement.getName());
if(null != inputElement){
if(null!= inputElement.getText()){
setValueByProperty(object,templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE),inputElement.getTextTrim());
}
}else{
System.out.println("注意:请求报文中不存在请求解析模板中的<"+templateElement.getName()+">节点");
}
}
else{
throw new Exception("解析模板中非终端节点<"+templateElement.getName()+">的Attribute属性缺失");
}
}
}catch(Exception e){
throw new Exception("根据解析模板递归解析xml失败"+e.getMessage());
}
return object;
}
/**
* @param templateElement xml模板节点
* @param outputParentElement 返回xml节点
* @param object 需处理的对象
* @param isTemplateRoot 是否为模板根节点
* @throws Exception
*/
private void getAnalyticalXml(Element templateElement,Element outputParentElement,
Object object,boolean isTemplateRoot) throws Exception{
try{
//非终端节点
if(templateElement.elements().size() != 0 ){
if(null != templateElement.attributeValue(ATTRIBUTE_OBJECTTYPE) && null != templateElement.attributeValue(ATTRIBUTE_ISARRAY)){
Class<?> templateElementClass = Class.forName(templateElement.attributeValue(ATTRIBUTE_OBJECTTYPE));
//对象数组节点
if( "true".equals(templateElement.attributeValue(ATTRIBUTE_ISARRAY))){
if( null != templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE)){
Object[] templateElementObjectArray = (Object[]) getValueByProperty(object,
templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE));
if(null != templateElementObjectArray){
//返回的xml中,非终端节点个数由相对应对象数组中对象的数量
for(int i = 0;i < templateElementObjectArray.length;i++){
//对象数组类型非终端节点根据对象个数循环生成
Element outputElement = outputParentElement.addElement(templateElement.getName());
Object templateElementObject = templateElementClass.cast(templateElementObjectArray[i]);
//循环处理非终端节点下的子节点,即循环处理当前解析节点代表的对象的属性
for(Iterator<?> templateElementIterator = templateElement.elementIterator();templateElementIterator.hasNext();){
Element templateChildElement = (Element) templateElementIterator.next();
//递归处理各节点
getAnalyticalXml(templateChildElement,outputElement,templateElementObject,false);
}
}
}else{
//响应解析模板中非终端节点获取对象数组为null时,生成空节点
outputParentElement.addElement(templateElement.getName());
System.out.println("注意:响应解析模板中非终端节点<"+templateElement.getName()+">获取相应对象数组为null");
}
}else{
throw new Exception("响应解析模板中非终端节点<"+templateElement.getName()+">的Attribute属性缺失");
}
}
//非对象数组节点
else{
//判断是否为响应解析模板根节点元素
if(isTemplateRoot){
if(null != object){
Object templateElementObject = templateElementClass.cast(object);
//循环处理非终端节点下子节点,即循环处理当前解析节点代表的对象属性
for(Iterator<?> templateElementIterator = templateElement.elementIterator();templateElementIterator.hasNext();){
Element templateChildElement = (Element) templateElementIterator.next();
//递归处理各节点
getAnalyticalXml(templateChildElement,outputParentElement,templateElementObject,false);
}
}else{
System.out.println("注意:转换为Xml的数据对象为null");
}
}else{
if(null != templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE)){
//非对象数组类型非终端节点根据对象唯一生成
Element outputElement = outputParentElement.addElement(templateElement.getName());
Object templateElementObject = templateElementClass.cast(
getValueByProperty(object,templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE)));
if( null != templateElementObject){
//循环处理非终端节点下子节点,即循环处理当前解析节点代表的对象的属性
for(Iterator<?> templateElementIterator = templateElement.elementIterator();templateElementIterator.hasNext();){
Element templateChildElement = (Element) templateElementIterator.next();
//递归处理各节点
getAnalyticalXml(templateChildElement,outputElement,templateElementObject,false);
}
}else{
System.out.println("注意:响应解析模板中非终端节点<"+templateElement.getName()+">获取相应对象数组为null");
}
}else{
throw new Exception("响应解析模板中非终端节点<"+templateElement.getName()+">的Attribute属性缺失");
}
}
}
}else{
throw new Exception("响应解析模板中非终端节点<"+templateElement.getName()+">的Attribute属性缺失");
}
}
//终端节点
else{
//根据响应解析模板生成响应终端节点,终端节点代表对象的简单类型属性
Element outputElement = outputParentElement.addElement(templateElement.getName());
if(null != templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE)){
String propertyValue = String.valueOf(getValueByProperty(object,templateElement.attributeValue(ATTRIBUTE_ATTRIBUTE)));
if(propertyValue != null && !propertyValue.isEmpty()){
//节点赋值
outputElement.setText(propertyValue);
}
}else{
throw new Exception("响应解析模板中终端节点<"+templateElement.getName()+">的Attribute属性缺失");
}
}
}catch(Exception e){
}
}
/**
* @param elements
* @param nodeName
* @return 文档中制定的第一个节点,如果遍历整个文档没有找到则返回null
* @throws Exception
*/
@SuppressWarnings("unchecked")
private Element getElementByName(List<Element> elements,String nodeName) throws Exception{
List<Element> childrens = new LinkedList<Element>();
for(Element e:elements){
if(e.getName().equals(nodeName)){
return e;
}
childrens.addAll(e.elements());
}
if(null != childrens && childrens.size() > 0){
return getElementByName(childrens,nodeName);
}else{
return null;
}
}
/**
* 取theClass类型propertyName属性的getter方法
* @param theClass
* @param propertyName
* @return 找不到返回null
*/
private Method getterMethod(Class<? extends Object> theClass,String propertyName){
return ClassInfo.getInstance(theClass).getGetter(propertyName);
}
/**
* 取theClass类型propertyName属性的setter方法
* @param theClass
* @param propertyName
* @return 找不到返回null
*/
private Method setterMethod(Class<? extends Object> theClass,String propertyName){
return ClassInfo.getInstance(theClass).getSetter(propertyName);
}
/**
* 通过反射机制,获取该属性值
* @param bean
* @param propertyName
* @return 如果找不到返回null
*/
private Object getValueByProperty(Object bean,String propertyName){
Class<? extends Object> beanClass = bean.getClass();
Method getterMethod = getterMethod(beanClass,propertyName);
try {
return getterMethod.invoke(bean, new Object[]{});
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 通过反射机制,给属性赋值
* @param bean
* @param propertyName
* @param value
* @return
*/
private Object setValueByProperty(Object bean,String propertyName,Object value){
Class<? extends Object> beanClass = bean.getClass();
Method setterMethod = setterMethod(beanClass,propertyName);
if(null != value){
try {
setterMethod.invoke(bean, new Object[]{value});
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return bean;
}
}
测试类(main方法)
package logUtil;
public class MainTest {
public static void main(String[] args) {
StringBuffer strb = new StringBuffer();
strb.append("<?xml version='1.0' encoding='UTF-8'?>");
strb.append("<Family>");
strb.append("<FamilyName>李想和邹丽家</FamilyName>");
strb.append("<Address>八卦岭</Address>");
strb.append("<Members>");
strb.append("<Member>");
strb.append("<MemberName>李想</MemberName>");
strb.append("<MemberAger>25</MemberAger>");
strb.append("</Member>");
strb.append("<Member>");
strb.append("<MemberName>邹丽</MemberName>");
strb.append("<MemberAger>24</MemberAger>");
strb.append("</Member>");
strb.append("<Member>");
strb.append("<MemberName>宝宝</MemberName>");
strb.append("<MemberAger>0.6</MemberAger>");
strb.append("</Member>");
strb.append("</Members>");
strb.append("</Family>");
String str = strb.toString();
System.out.println(str);
XmlObjectTransform trs = new XmlObjectTransformImpl();
try {
FamilyInfoVO f = (FamilyInfoVO) trs.xmlToObject("logUtil/request-family.xml", str);
System.out.println(f);
String xml = trs.objectToXml("logUtil/request-family.xml", f, "UTF-8");
System.out.println(xml);
} catch (Exception e) {
e.printStackTrace();
}
}
}
pojo类1
package logUtil;
public class FamilyInfoVO {
private String familyName;
private String address;
private MembersVO members;
public String getFamilyName() {
return familyName;
}
public void setFamilyName(String familyName) {
this.familyName = familyName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public MembersVO getMembers() {
return members;
}
public void setMembers(MembersVO members) {
this.members = members;
}
@Override
public String toString() {
return "FamilyInfoVO [familyName=" + familyName + ", address="
+ address + ", members=" + members + "]";
}
}
pojo类2
package logUtil;
import java.util.Arrays;
public class MembersVO {
private MemberVO[] members;
public MemberVO[] getMembers() {
return members;
}
public void setMembers(MemberVO[] members) {
this.members = members;
}
@Override
public String toString() {
return "MembersVO [members=" + Arrays.toString(members) + "]";
}
}
pojo类3
package logUtil;
public class MemberVO {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
private String age;
@Override
public String toString() {
return "MemberVO [name=" + name + ", age=" + age + "]";
}
}
xml模板
<?xml version="1.0" encoding="UTF-8"?>
<Family ObjectType="logUtil.FamilyInfoVO" isArray="false">
<FamilyName Attribute="familyName" DataType="java.lang.String"/>
<Address Attribute="address" DataType="java.lang.String"/>
<Members Attribute="members" ObjectType="logUtil.MembersVO" isArray="false">
<Member Attribute="members" ObjectType="logUtil.MemberVO" isArray="true">
<MemberName Attribute="name" DataType="java.lang.String"/>
<MemberAger Attribute="age" DataType="java.lang.String"/>
</Member>
</Members>
</Family>