项目中很多时候需要将xml内容转换成java对象来处理,这样一来数据就直观,操作起来也更加方便,
下面介绍下如何通过java将xml内容转换java对象。
1、MyXml.xml
<?xml version="1.0" encoding="UTF-8"?>
<sysConfig id="sys">
<say id="a" name="b">
<content value="xx"></content>
</say>
<hello id="a" name="b">
<content value="xx"></content>
</hello>
<hello id="a" name="b">
<content value="xx"></content>
</hello>
<Test id="a" name="b">
<content value="xx"></content>
<content value="xx"></content>
</Test>
<ArrayTest id="a" name="b">
<content value="xx1"></content>
<content value="xx2"></content>
</ArrayTest>
<ArrayTest id="a" name="b">
<content value="xx3"></content>
<content value="xx4"></content>
</ArrayTest>
</sysConfig>
2、对应java类结构
/**
*
*/
package org.common.util;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
class Base {
SysConfig sysConfig;
public SysConfig getSysConfig() {
return sysConfig;
}
public void setSysConfig(SysConfig sysConfig) {
this.sysConfig = sysConfig;
}
}
class A extends Base {
@Override
public String toString() {
return "A [sysConfig=" + sysConfig + "]";
}
}
class B {
SysConfig sysConfig;
public SysConfig getSysConfig() {
return sysConfig;
}
public void setSysConfig(SysConfig sysConfig) {
this.sysConfig = sysConfig;
}
@Override
public String toString() {
return "B [sysConfig=" + sysConfig + "]";
}
}
class SysConfig {
Say say;
String id;
Hello[] hello;
Test test;
ArrayTest[] arrayTest;
public Say getSay() {
return say;
}
public void setSay(Say say) {
this.say = say;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Hello[] getHello() {
return hello;
}
public void setHello(Hello[] hello) {
this.hello = hello;
}
public Test getTest() {
return test;
}
public void setTest(Test test) {
this.test = test;
}
public ArrayTest[] getArrayTest() {
return arrayTest;
}
public void setArrayTest(ArrayTest[] arrayTest) {
this.arrayTest = arrayTest;
}
@Override
public String toString() {
return "SysConfig [arrayTest=" + Arrays.toString(arrayTest) + ", hello=" + Arrays.toString(hello) + ", id="
+ id + ", say=" + say + ", test=" + test + "]";
}
}
class Hello {
Content content;
String id;
String name;
public Content getContent() {
return content;
}
public void setContent(Content content) {
this.content = content;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Hello [content=" + content + ", id=" + id + ", name=" + name + "]";
}
}
class Say {
Content content;
String id;
String name;
public Content getContent() {
return content;
}
public void setContent(Content c) {
this.content = c;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Say [c=" + content + ", id=" + id + ", name=" + name + "]";
}
}
class Test {
Content[] content;
public Content[] getContent() {
return content;
}
public void setContent(Content[] content) {
this.content = content;
}
@Override
public String toString() {
return "Test [content=" + Arrays.toString(content) + "]";
}
}
class ArrayTest {
Content[] content;
public Content[] getContent() {
return content;
}
public void setContent(Content[] content) {
this.content = content;
}
@Override
public String toString() {
return "Test [content=" + Arrays.toString(content) + "]";
}
}
class Content {
String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "content [value=" + value + "]";
}
}
/**
* @author Administrator
*
*/
public class Example {
/**
* @param args
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
* @throws ClassNotFoundException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws DOMException
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException,
IllegalArgumentException, DOMException, InstantiationException, IllegalAccessException,
InvocationTargetException, ClassNotFoundException {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
"\\WebRoot\\WEB-INF\\classes\\org\\common\\util\\MyXml.xml");
A a = (A) XMLToObject.getInstance().transform(doc, A.class, true);
System.out.println(a.toString());
B b = (B) XMLToObject.getInstance().transform(doc, B.class, false);
System.out.println(b.toString());
}
}
3、实现类XMLToObject.java
/**
*
*/
package org.common.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* @author yangguangftlp
*
*/
@SuppressWarnings("unchecked")
public class XMLToObject {
public static String M_SET = "set";
private static XMLToObject instance;
private XMLToObject() {
}
/**
* 获取实例
*
* @return
*/
public static XMLToObject getInstance() {
if (null == instance) {
synchronized (XMLToObject.class) {
if (null == instance) {
instance = new XMLToObject();
}
}
}
return instance;
}
/**
* 将xml转换Object
*
* @param doc
* 文档对象
* @param objClass
* class
* @param flag
* 是否获取 objClass 继承的所有方法
* @return 返回 生成objClass 实例对象
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws DOMException
* @throws ClassNotFoundException
*/
public Object transform(Document doc, Class objClass, boolean flag) throws InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, DOMException,
ClassNotFoundException {
if (null == doc) {
throw new IllegalArgumentException("doc is null!");
}
if (null == objClass) {
throw new IllegalArgumentException("objClass is null!");
}
return doRootNode(doc.getDocumentElement(), objClass.newInstance(), flag);
}
public Object doRootNode(Element root, Object obj, boolean flag) throws ClassNotFoundException,
IllegalAccessException, InvocationTargetException, InstantiationException {
if (null != root) {
// 获取obj上所有定义public方法
Method method = getMethods(M_SET, obj.getClass(), flag).get(generateMethodName(M_SET, root.getNodeName()));
if (null != method && method.getParameterTypes().length == 1) {
Class paramType = method.getParameterTypes()[0];
if (!paramType.isArray() && !paramType.isPrimitive()) {
Object paramObj = paramType.newInstance();
// 处理节点属性
doAttributes(root, paramObj, getMethods(M_SET, paramType, flag));
method.invoke(obj, paramObj);
// 获取子节点
doChildNode(root.getChildNodes(), paramObj, flag);
}
}
}
return obj;
}
/**
* 通过节点名称构造方法名
*
* @param prefix
* get
* @param name
* 节点名称
* @return 返回方法名
*/
private String generateMethodName(String prefix, String name) {
return new StringBuffer(prefix).append(Character.toUpperCase(name.charAt(0))).append(name.substring(1))
.toString();
}
/**
* 处理属性
*
* @param root
* @param paramObj
* @param temp
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public void doAttributes(Node node, Object paramObj, Map<String, Method> methods) throws IllegalAccessException,
InvocationTargetException {
// 处理node属性
Method method = null;
Node nameNode = null;
NamedNodeMap nameNodeMap = node.getAttributes();
if (null != nameNodeMap) {
for (int i = 0, length = nameNodeMap.getLength(); i < length; i++) {
nameNode = nameNodeMap.item(i);
method = methods.get(generateMethodName(M_SET, nameNode.getNodeName()));
if (null != method && method.getParameterTypes().length == 1
&& (method.getParameterTypes()[0] == String.class)) {
method.invoke(paramObj, nameNode.getNodeValue());
}
}
}
}
/**
* 处理子节点
*
* @param nodeList
* @param obj
* @param flag
* @return
* @throws IllegalArgumentException
* @throws DOMException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws InstantiationException
* @throws ClassNotFoundException
*/
public Object doChildNode(NodeList nodeList, Object obj, boolean flag) throws IllegalArgumentException,
DOMException, IllegalAccessException, InvocationTargetException, InstantiationException,
ClassNotFoundException {
if (null != nodeList) {
Map<String, Method> methodMap = getMethods(M_SET, obj.getClass(), flag);
Map<String, List<Object>> objMap = new HashMap<String, List<Object>>();
Method method = null;
Node childNode = null;
String methodName = null;
Object paramObj = null;
for (int i = 0, len = nodeList.getLength(); i < len; i++) {
childNode = nodeList.item(i);
if (childNode instanceof Element) {
methodName = generateMethodName(M_SET, childNode.getNodeName());
method = methodMap.get(methodName);
if (null != method && method.getParameterTypes().length == 1) {
paramObj = method.getParameterTypes()[0].isArray() ? getParamClass(
method.getParameterTypes()[0].getName()).newInstance() : method.getParameterTypes()[0]
.newInstance();
if (!objMap.containsKey(methodName)) {
objMap.put(methodName, new ArrayList<Object>());
}
doAttributes(childNode, paramObj, getMethods(M_SET, paramObj.getClass(), flag));
objMap.get(methodName).add(doChildNode(childNode.getChildNodes(), paramObj, flag));
}
}
}
for (Entry<String, List<Object>> entry : objMap.entrySet()) {
method = methodMap.get(entry.getKey());
if (method.getParameterTypes()[0].isArray()) {
method.invoke(obj, (Object) Arrays.copyOf(entry.getValue().toArray(), entry.getValue().size(),
(Class) method.getParameterTypes()[0]));
} else {
method.invoke(obj, entry.getValue().get(0));
}
}
}
return obj;
}
private Class getParamClass(String name) throws ClassNotFoundException, InstantiationException,
IllegalAccessException {
StringBuffer className = new StringBuffer(name);
className.delete(0, 2).deleteCharAt(className.length() - 1);
return Class.forName(className.toString());
}
/**
* 根据前缀获取class上的方法
*
* @param prefix
* 方法名前缀
* @param cls
* class
* @param flag
* 自定义方法还是所有方法
* @return 返回prefix前缀的所有方法
*/
public Map<String, Method> getMethods(String prefix, Class cls, boolean flag) {
Map<String, Method> methodMap = new HashMap<String, Method>();
Method[] methods = flag ? cls.getMethods() : cls.getDeclaredMethods();
if (null != methods) {
for (Method m : methods) {
if (m.getName().startsWith(prefix) && Modifier.PUBLIC == m.getModifiers()) {
methodMap.put(m.getName(), m);
}
}
}
return methodMap;
}
/**
* 根据前缀获取class上的方法
*
* @param prefix
* 方法名前缀
* @param cls
* class
* @param flag
* 自定义方法还是所有方法
* @return 返回prefix前缀的所有方法
* @throws NoSuchMethodException
* @throws SecurityException
*/
public Method getMethod(String name, boolean flag, Class cls, Class... parameterTypes) throws SecurityException,
NoSuchMethodException {
Method method = flag ? cls.getMethod(name, parameterTypes) : cls.getDeclaredMethod(name, parameterTypes);
return method;
}
}
4、运行代码
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException,
IllegalArgumentException, DOMException, InstantiationException, IllegalAccessException,
InvocationTargetException, ClassNotFoundException {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
"\\WebRoot\\WEB-INF\\classes\\org\\common\\util\\MyXml.xml");
A a = (A) XMLToObject.getInstance().transform(doc, A.class, true);
System.out.println(a.toString());
B b = (B) XMLToObject.getInstance().transform(doc, B.class, false);
System.out.println(b.toString());
}
结果:
A [sysConfig=SysConfig [arrayTest=[Test [content=[content [value=xx1], content [value=xx2]]], Test [content=[content [value=xx3], content [value=xx4]]]], hello=[Hello [content=content [value=xx], id=a, name=b], Hello [content=content [value=xx], id=a, name=b]], id=sys, say=Say [c=content [value=xx], id=a, name=b], test=Test [content=[content [value=xx], content [value=xx]]]]]
B [sysConfig=SysConfig [arrayTest=[Test [content=[content [value=xx1], content [value=xx2]]], Test [content=[content [value=xx3], content [value=xx4]]]], hello=[Hello [content=content [value=xx], id=a, name=b], Hello [content=content [value=xx], id=a, name=b]], id=sys, say=Say [c=content [value=xx], id=a, name=b], test=Test [content=[content [value=xx], content [value=xx]]]]]
规则说明:首先定义数据模型的时候必须提供get和set方法,而且get和set后面的名称必须是xml中的节点名称,例如:Base setSysConfig方法中SysConfig对应xml中的sysConfig,注意xml节点名称首字母不区分大小写(代码会将xml中节点名称首字母变成大写)。
注意:整个实现是通过java反射来处理, 以上代码实现在属性为string、和自定义类上通过。