XStream解析XML文本并用反射机制转换为对象

xml文本格式是网络通信中最常用的格式,最近特别研究了一下如何解析xml文本并转换为对象,现在分享一下我最近的学习成果~

       先列一下本例中需要解析的xml文本:

Xml代码   收藏代码
  1. <results name="list">  
  2.     <row pubtime="2016-04-13 16:40:13" author="APP"  id="140" title="什么是公告" content="公告,是公开宣告。" />  
  3.     <row pubtime="2016-04-13 16:36:50" author="网站" id="138" title="12345678" content="12345678"  />  
  4.     <row pubtime="2016-04-06 15:02:44" author="网站" id="134" title="关于网站用户注册流程说明1" content="关于用户注册流程说明"  />  
  5.     <row pubtime="2016-03-30 18:32:13" author="APP"  id="126" title="关于网站使用说明" content="测试"  />  
  6.     <row pubtime="2016-03-30 18:29:26" author="网站" id="125" title="关于手机App使用说明" content="123"  />  
  7. </results>  

 

       讲一下我的思路,我选择使用XStream来解析xml文本,因为xstream在转换对象方面会比dom4j更优秀一些,它是通过注解方式来声明对应结点的,在操作上会更直观方便。首先会将整个文本转换成一个Results类对象,而每一个row结点作为一个HashMap放入到Results类对象的List列表中,最后会将每一个HashMap读取出来通过JAVA的反射机制转换为Info对象,并生成List列表下载

 

Info类代码   收藏代码
  1. public class Info {  
  2.   
  3.     private String id;  
  4.     private String title;  
  5.     private String content;  
  6.     private String author;  
  7.     private String pubtime;  
  8.     public String getId() {  
  9.         return id;  
  10.     }  
  11.     public void setId(String id) {  
  12.         this.id = id;  
  13.     }  
  14.     public String getTitle() {  
  15.         return title;  
  16.     }  
  17.     public void setTitle(String title) {  
  18.         this.title = title;  
  19.     }  
  20.     public String getContent() {  
  21.         return content;  
  22.     }  
  23.     public void setContent(String content) {  
  24.         this.content = content;  
  25.     }  
  26.     public String getAuthor() {  
  27.         return author;  
  28.     }  
  29.     public void setAuthor(String author) {  
  30.         this.author = author;  
  31.     }  
  32.     public String getPubtime() {  
  33.         return pubtime;  
  34.     }  
  35.     public void setPubtime(String pubtime) {  
  36.         this.pubtime = pubtime;  
  37.     }  
  38.     @Override  
  39.     public String toString() {  
  40.         return "Info [author=" + author + ", content=" + content + ", id=" + id  
  41.                 + ", pubtime=" + pubtime + ", title=" + title + "]";  
  42.     }  
  43.   
  44.       
  45.       
  46. }  

 

Row类代码   收藏代码
  1. @XStreamConverter(RowConverter.class)  
  2. public class Row extends HashMap<String, String> {  
  3.     private static final long serialVersionUID = 5619951409573339302L;  
  4. }  下载

 

Results代码   收藏代码
  1. @XStreamAlias("results")  
  2. public class Results {  
  3.     @XStreamAlias("name")  
  4.     @XStreamAsAttribute  
  5.     private String name;  
  6.   
  7.     @XStreamImplicit(itemFieldName = "row")  
  8.     private List<Row> rows;  
  9.   
  10.     public String getName() {  
  11.         return name;  
  12.     }  
  13.   
  14.     public void setName(String name) {  
  15.         this.name = name;  
  16.     }  
  17.   
  18.     public List<Row> getRows() {  
  19.         return rows;  
  20.     }  
  21.   
  22.     public void setRows(List<Row> rows) {  
  23.         this.rows = rows;  
  24.     }  
  25.   
  26.   
  27. }  

 

Rowconverter类代码   收藏代码
  1. public class RowConverter extends AbstractCollectionConverter {  
  2.   
  3.     public RowConverter(Mapper mapper) {  
  4.         super(mapper);  
  5.         // TODO Auto-generated constructor stub  
  6.     } 下载 
  7.   
  8.     @Override  
  9.     public boolean canConvert(Class arg0) {  
  10.         // TODO Auto-generated method stub  
  11.         return Row.class.equals(arg0);  
  12.     }  
  13.   
  14.     @Override  
  15.     public void marshal(Object arg0, HierarchicalStreamWriter writer,  
  16.             MarshallingContext arg2) {  
  17.         // TODO Auto-generated method stub  
  18.         Row map = (Row) arg0;  
  19.         for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {  
  20.             Map.Entry entry = (Map.Entry) iterator.next();  
  21.             writer.addAttribute(entry.getKey().toString(), entry.getValue().toString());  
  22.         }  
  23.     }  
  24.   
  25.     @Override  
  26.     public Object unmarshal(HierarchicalStreamReader reader,  
  27.             UnmarshallingContext context) {  
  28.         // TODO Auto-generated method stub  
  29.          Row map = new Row();  
  30.         populateMap(reader, context, map);  
  31.         return map;  
  32.     }  
  33.   
  34.      protected void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, Row map) {  
  35.             Iterator<String> iterator = reader.getAttributeNames();  
  36.             while (iterator.hasNext()) {  
  37.                 Object key = iterator.next();  
  38.                 String value = reader.getAttribute((String) key);  
  39.                 map.put(key.toString(), value.toString());  
  40.             }  
  41.         }  
  42. }  

 RowConverter是一个转换器类,作用是将每一个row结点转变一个HashMap。 

 

测试类:

Java代码   收藏代码
  1. public class Xstream {  
  2.       
  3.     private static String  xml;  
  4.   
  5.     public static void main(String[] args) throws Exception{  
  6.         //初始化  
  7.         init();  
  8.   
  9.         XStream xstream = new XStream(new XppDriver(new XmlFriendlyReplacer("_-""_")));  
  10.         //解析xml文本  
  11.         xstream.processAnnotations(Results.class);  
  12.         Results results = (Results) xstream.fromXML(xml);  
  13.         //将解析出来的Results类对象转化成list列表  
  14.         List<Info> list = createList(Info.class,results);  
  15.           
  16.         for(int i=0;i<list.size();i++){  
  17.             //打印  
  18.             Info info = list.get(i);  
  19.             System.out.println(info.toString());  
  20.         }  
  21.       下载
  22.     }  
  23.     public static void init(){  
  24.         //初始化xml文本  
  25.         xml ="<results name=\"list\"><row pubtime=\"2016-04-13 16:40:13\" author=\"APP\"  id=\"140\" title=\"什么是公告\" content=\"公告,是公开宣告。\" /><row pubtime=\"2016-04-13 16:36:50\" author=\"网站\" id=\"138\" title=\"12345678\" content=\"12345678\"  /><row pubtime=\"2016-04-06 15:02:44\" author=\"网站\" id=\"134\" title=\"关于网站用户注册流程说明1\" content=\"关于用户注册流程说明\"  /><row pubtime=\"2016-03-30 18:32:13\" author=\"APP\"  id=\"126\" title=\"关于网站使用说明\" content=\"测试\"  /><row pubtime=\"2016-03-30 18:29:26\" author=\"网站\" id=\"125\" title=\"关于手机App使用说明\" content=\"123\"  /></results>";  
  26.     }  
  27.     public static <T> List createList(Class<T> clz ,Results results) throws Exception{  
  28.         List list = new ArrayList();  
  29.         for(Row row :results.getRows()){  
  30.             //根据class和Row生成对象放入list  
  31.             list.add(createObject(clz,row));  
  32.               
  33.         }  
  34.         return list;  
  35.     }  
  36.     public static <T> T createObject(Class<T> clazz ,Row row) throws Exception{  
  37.         //初始化对象  
  38.         T obj = clazz.newInstance();  
  39.         //遍历Info类中所有方法  
  40.         for (Method method : clazz.getDeclaredMethods()) {  
  41.             String methodName = method.getName();  
  42.             Class[] perams = method.getParameterTypes();  
  43.             //找到set开头,长度大于3,并且入参数量为1的方法  
  44.             if (methodName.startsWith("set") && methodName.length() > 3 && perams.length == 1) {  
  45.                   
  46.                 String temp = methodName.substring(3, methodName.length());  
  47.                 //拿到属性名称  
  48.                 String fieldName = temp.toLowerCase();  
  49.                 //根据属性名称从HashMap中拿到对应的值  
  50.                 String value = row.get(fieldName);  
  51.                   
  52.                 if(value != null){  
  53.                     //拿到该方法入参的Class,根据入参类型来决定调用方法形式  
  54.                     Class  paramClass = perams[0];  
  55.                     if (String.class.equals(paramClass)) {  
  56.                         method.invoke(obj, value);  
  57.                     } else if (Integer.class.equals(paramClass) || int.class.equals(paramClass)) {  
  58.                         method.invoke(obj, Integer.valueOf(value));  
  59.                     } else if (Long.class.equals(paramClass) || long.class.equals(paramClass)) {  
  60.                         method.invoke(obj, Long.valueOf(value));  
  61.                     } else if (BigDecimal.class.equals(paramClass)) {  
  62.                         method.invoke(obj, new BigDecimal(value));  
  63.                     } else if (Boolean.class.equals(paramClass) || boolean.class.equals(paramClass)) {  
  64.                         if(value.equals("true")||value.equals("TRUE"))  
  65.                             method.invoke(obj, true);  
  66.                         if(value.equals("false")||value.equals("FALSE"))  
  67.                             method.invoke(obj, false);  
  68.                     }  
  69.                 }  
  70.               
  71.             }  
  72.         }  
  73.         return obj;  
  74.     }  
  75. }  

 

最后是输出效果:

Java代码   收藏代码
  1. Info [author=APP, content=公告,是公开宣告。, id=140, pubtime=2016-04-13 16:40:13, title=什么是公告]  
  2. Info [author=网站, content=12345678, id=138, pubtime=2016-04-13 16:36:50, title=12345678]  
  3. Info [author=网站, content=关于用户注册流程说明, id=134, pubtime=2016-04-06 15:02:44, title=关于网站用户注册流程说明1]  
  4. Info [author=APP, content=测试, id=126, pubtime=2016-03-30 18:32:13, title=关于网站使用说明]  
  5. Info [author=网站, content=123, id=125, pubtime=2016-03-30 18:29:26, title=关于手机App使用说明]  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值