[工具库]JOXMLBuilder工具类——一键把多个bean对象数据转换为XML格式数据


本人大四即将毕业的准程序员(JavaSE、JavaEE、android等)一枚,小项目也做过一点,于是乎一时兴起就写了一些工具。

我会在本博客中陆续发布一些平时可能会用到的工具。

代码质量可能不是很好,大家多担待!

代码或者思路有不妥之处,还希望大牛们能不吝赐教哈!

 

以下代码为本人原创,转载请注明:

本文转载,来自:http://www.cnblogs.com/tiantianbyconan/archive/2013/02/19/2917398.html

 

JOXMLBuilder工具类:一键把多个域对象数据转换为XML格式数据,方便用于数据的传输和交互。功能类似于通过Gson来生成Json数据。

源码如下:

View Code

  1 package com.wangjie.extrautil.joxmlbuilder;
2
3 import java.lang.reflect.Field;
4 import java.lang.reflect.Method;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Set;
10
11 /
12
13 @author wangjie
14 @version 创建时间:2013-2-3 下午3:49:59
15 /
16 public class JOXMLBuilder {
17 private List<?> list; // 传入的List数据
18 private StringBuilder result = null;
19 private List<String> includes = null; // 要包含的属性列表
20 private List<String> excludes = null; // 要排除的属性列表
21
22 /
23 默认构造方法。<br>
24 使用此默认的构造方法之后必须要调用setList()传入List
25 /
26 public JOXMLBuilder() {
27
28 }
29 /**
30 此构造方法会把list中每项的所有属性信息都会生成在xml中。
31 @param list 所要生成xml的List数据源。
32 /
33 public JOXMLBuilder(List<?> list) {
34 this.list = list;
35 }
36 /
37 此构造方法提供list中每项属性信息的<b>包含</b>和<b>排除</b>。<br>
38 <ol>
39 <li>使用includes,不使用excludes:只生成在includes中的信息<br>
40 <li>不使用includes,使用excludes:只生成不在excludes中的信息<br>
41 <li>既使用includes,又使用exclude(不建议):<br>
42 - 如果includes中和excludes中的信息不冲突,则生成不在excludes中的信息<br>
43 - 如果includes中和excludes中的信息冲突(某个属性都出现在这两个数组中),则冲突部分的信息还是会生成<br>
44 <li>includes和excludes都不使用,则会把list中每项的所有属性信息都会生成在xml中
45 </ol>
46 @param list 所要生成Json的List数据源。
47 @param includes 所要包含的属性名称数组。
48 @param excludes 所要排除的属性名称数组。
49 */
50 public JOXMLBuilder(List<?> list, String[] includes, String[] excludes) {
51 this.list = list;
52 this.includes = null == includes || includes.length == 0 ? null : Arrays.asList(includes);
53 this.excludes = null == excludes || excludes.length == 0 ? null : Arrays.asList(excludes);
54 }
55 /
56 返回正在进行生成xml文件的信息来源List。
57 @author wangjie
58 @return 返回正在进行生成xml文件的信息来源List。
59 /
60 public List<?> getList() {
61 return list;
62 }
63 /
64 可使用此方法来传入、替换JOXMLBuilder对象中的List对象。
65 @author wangjie
66 @param list 所要生成xml的List数据源。
67 @return 返回当前JOXMLBuilder对象
68 */
69 public JOXMLBuilder setList(List<?> list) {
70 this.list = list;
71 return this;
72 }
73 /
74 设置包含的属性信息。
75 @author wangjie
76 @param incFieldName 要包含的属性名
77 @return 返回当前JOXMLBuilder对象
78 /
79 public JOXMLBuilder setIncludes(String… incFieldName) {
80 this.includes = null == incFieldName || incFieldName.length == 0 ? null : Arrays.asList(incFieldName);
81 return this;
82 }
83 /**
84 设置排除的属性信息。
85 @author wangjie
86 @param excFieldName 要排除的属性名
87 @return 返回当前JOXMLBuilder对象
88 /
89 public JOXMLBuilder setExcludes(String… excFieldName) {
90 this.excludes = null == excFieldName || excFieldName.length == 0 ? null : Arrays.asList(excFieldName);
91 return this;
92 }
93 /
94 获得指定Class类型的所有属性,并打印在控制台上。
95 @author wangjie
96 */
97 public Field[] getFields(Class<?> clazz) {
98 Field[] fields = clazz.getDeclaredFields();
99 System.out.print(“fields of the class that named “ + clazz.getName() + “: “);
100 for(Field field : fields){
101 System.out.print(field.getName() + “, “);
102 }
103 System.out.println();
104 return fields;
105 }
106
107 /
108 根据list中的对象来生成对应的xml文件。
109 @author wangjie
110 @return 返回生成的xml字符串。
111 @throws Exception 如果List检验不通过,则抛出异常
112 /
113 public StringBuilder xmlBuild() throws Exception{
114 //检验传入的List是否有效
115 checkValidityList();
116 //XML文件开始生成————————-
117 result = new StringBuilder(“<?xml version=\”1.0\” encoding=\”utf-8\”?>”);
118 xmlSubBuild(list); // 递归生成
119 return result;
120 }
121 /**
122 生成xml可递归部分的子数据(根据某些对象组成的List来生成属性xml文件)。
123 @author wangjie
124 @param list
125 /
126 private void xmlSubBuild(List<?> list){
127 Class<?> clazz = list.get(0).getClass(); // 获取对应的Class对象
128 Object curObj = null; // 每次循环当前的类对象(资源)
129 int listLength = list.size(); // 类对象个数
130 String simpleName = clazz.getSimpleName(); // 获取类名(不含包名)
131
132 result.append(“<” + simpleName + “All>”); // 根标签开始
133
134 for(int i = 0; i < listLength; i++){
135 curObj = list.get(i);
136 xmlSubSubBuild(curObj, list); // 子数据递归
137 }
138
139 result.append(“</“ + simpleName + “All>”); // 根标签结束
140 }
141 /**
142 生成xml可递归部分的子子数据(根据某个对象来生成属性xml文件)。
143 @author wangjie
144 @param curObj 要生成xml文件的那个对象
145 @param list curObj参数属于的那个List
146 /
147 private void xmlSubSubBuild(Object curObj, List<?> list){
148 String fieldName = “”; // 每次要调用的属性名
149 String methodName = “”; // 每次要调用的方法名
150 Method method = null;; // 每次要调用的方法
151 Object value = “”; // 每次要获得的属性值(子标签)
152
153 Class<?> clazz = curObj.getClass();
154 Field[] fields = getFields(clazz); // 获得对应类型的所有变量
155 int fieldsLength = fields.length; // 类对象的属性数量
156
157 String simpleName = clazz.getSimpleName(); // 获取类名(不含包名)
158
159 result.append(“<” + simpleName + “>”);
160
161
162 for(int j = 0; j < fieldsLength; j++){
163 fieldName = fields[j].getName(); // 获取对应属性名
164
165 if(list == this.list){ // 只在最外层的类的属性中进行排除包含
166 // 使用includes,不使用excludes:只生成在includes中的信息
167 if(null != includes && null == excludes){
168 if(!includes.contains(fieldName)){
169 continue;
170 }
171 }
172
173 //不使用includes,使用excludes:只生成不在excludes中的信息
174 if(null == includes && null != excludes){ // 只使用了不包含
175 if(excludes.contains(fieldName)){
176 continue;
177 }
178 }
179
180 //既使用includes,又使用exclude(不建议):
181 //- 如果includes中和excludes中的信息不冲突,则生成不在excludes中的信息
182 //- 如果includes中和excludes中的信息冲突(某个属性都出现在这两个数组中),则冲突部分的信息还是会生成
183 if(null != includes && null != excludes){ // 既使用了包含,又使用了不包含
184 if(!includes.contains(fieldName) && excludes.contains(fieldName)){
185 continue;
186 }
187 }
188 }
189
190 methodName = getGetterMethodNameByFieldName(fields[j]);
191 try {
192 method = clazz.getDeclaredMethod(methodName, new Class[]{});
193 method.setAccessible(true);
194 value = method.invoke(curObj, new Object[]{});
195 //*
196 if(fields[j].getType() == List.class){ // 如果属性是List类型
197 List<?> subList = (List<?>)value;
198 xmlSubBuild(subList); // 子数据递归
199 }else if(fields[j].getType() == Set.class){ // 如果属性是Set类型的
200 Set<?> subSet = (Set<?>)value;
201 Iterator<?> iter = subSet.iterator();
202 List<Object> subList = new ArrayList<Object>();
203 while(iter.hasNext()){
204 subList.add(iter.next());
205 }
206 xmlSubBuild(subList); // 子数据递归
207 }
208 // 如果ClassLoader不是null表示该类不是启动类加载器加载的,不是Java API的类,是自己写的java类
209 else if(null != fields[j].getType().getClassLoader()){
210 xmlSubSubBuild(value, null); // 子子数据递归
211 }
212 else{ // 其它类型都认为是普通文本类型
213 value = value.toString();
214 // 添加子元素(类属性)标签
215 result.append(“<” + fieldName + “>”)
216 .append(value)
217 .append(“</“ + fieldName + “>”);
218 }
219 //*
220 } catch (Exception e) {
221 e.printStackTrace();
222 }
223
224 }
225 result.append(“</“ + simpleName + “>”);
226 }
227
228 /
229 <ol>通过属性Field对象来获取getter方法的方法名。<br>
230 如果是boolean或Boolean类型(正则表达式来判断):isBorrow–>isBorrow();isborrow–>isIsborrow();<br>
231 否则:borrow–>getBorrow();
232 </ol>
233 @author wangjie
234 @param field 要生成getter方法的对应属性对象。
235 @return 返回getter方法的方法名。
236 /
237 private String getGetterMethodNameByFieldName(Field field){
238 String methodName = null;
239 String fieldName = field.getName();
240 // 解析属性对应的getter方法名
241 // 判断是否是boolean或Boolean类型:isBorrow–>isBorrow();isborrow–>isIsborrow()
242 if(field.getType() == boolean.class || field.getType() == Boolean.class){
243 if(fieldName.matches(“^is[A-Z].*”)){
244 methodName = fieldName;
245 }else{
246 methodName = “is” + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
247 }
248 }else{
249 methodName = “get” + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
250 }
251 return methodName;
252 }
253
254 /
255 检验传入的List的合法性(List是不是为null、长度是不是为0、是不是每项都是同一个类型)。
256 @author wangjie
257 @throws Exception 如果List为null, 或者长度为, 或者每项不是同一个类型, 抛出异常
258 /
259 private void checkValidityList() throws Exception{
260 if(null == list){
261 throw new Exception(“请保证传入的List不为null”);
262 }
263 int size = list.size();
264 if(list.size() == 0){
265 throw new Exception(“请保证传入的List长度不为0”);
266 }
267 for(int i = 1; i < size; i++){
268 if(list.get(0).getClass() != list.get(i).getClass()){
269 throw new Exception(“请保证传入的List每项都是同一个类型”);
270 }
271 }
272
273 }
274
275
276 }


 

使用方法如下:
例如:
Student类(该类有属性name,age,isBoy,books等属性;其中books属性是一个List,存放Book对象):


1 private String name;
2 private int age;
3 private boolean isBoy;
4 private List<Book> books;
5 //并实现getter和setter方法;

 

Book类(该类有属性name,author,number,length,width,isBorrowed等属性):


1 private String name;
2 private String author;
3 private int number;
4 private float length;
5 private float width;
6 private boolean isBorrowed;
7 //并实现getter和setter方法;

 

现在有一个List<Student>类型的数据,通过以下代码把该List转换为xml:


 1 List<Student> list = new ArrayList<Student>();
2
3 //构建几个Student对象,放入list中
4 //……
5
6 //完整数据版(不使用includes和excludes)
7 JOXMLBuilder jOXMLBuilder = new JOXMLBuilder(list);
8 jOXMLBuilder.xmlBuild().toString();
9
10 //或者使用包括/排除:
11 JOXMLBuilder jOXMLBuilder = new JOXMLBuilder(list, new String[]{“name”, “age”}, null);
12 jOXMLBuilder.xmlBuild().toString();
13
14 //或者使用方法链风格:
15 new JOXMLBuilder().setExcludes(“name”, “age”).xmlBuild().toString();

 

转换之后的xml(完整数据版(不使用includes和excludes)):


 1 <?xml version=”1.0” encoding=”utf-8”?>
2 <StudentAll>
3 <Student>
4 <name>hello</name>
5 <age>23</age>
6 <isBoy>true</isBoy>
7 <BookAll>
8 <Book>
9 <name>book1</name>
10 <author>author1</author>
11 <number>123</number>
12 <length>23.5</length>
13 <width>18.0</width>
14 <isBorrowed>true</isBorrowed>
15 </Book>
16 <Book>
17 <name>book2</name>
18 <author>author2</author>
19 <number>43</number>
20 <length>42.23</length>
21 <width>30.57</width>
22 <isBorrowed>false</isBorrowed>
23 </Book>
24 </BookAll>
25 </Student>
26
27 <Student>
28 <name>world</name>
29 <age>22</age>
30 <isBoy>false</isBoy>
31 <BookAll>
32 <Book>
33 <name>book1</name>
34 <author>author1</author>
35 <number>123</number>
36 <length>23.5</length>
37 <width>18.0</width>
38 <isBorrowed>true</isBorrowed>
39 </Book>
40 <Book>
41 <name>book3</name>
42 <author>author3</author>
43 <number>875</number>
44 <length>20.59</length>
45 <width>15.08</width>
46 <isBorrowed>false</isBorrowed>
47 </Book>
48 <Book>
49 <name>book4</name>
50 <author>author4</author>
51 <number>165</number>
52 <length>22.75</length>
53 <width>19.61</width>
54 <isBorrowed>true</isBorrowed>
55 </Book>
56 </BookAll>
57 </Student>
58 </StudentAll>

 

 



来源博客:Wang Jie's Blog
本文链接:https://blog.wangjiegulu.com/2013/02/19/工具库-JOXMLBuilder工具类——一键把多个bean对象数据转换为XML格式数据/
版权声明:本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处。