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

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

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

Xml代码

收藏代码

  1. <resultsname="list">

  2. rowpubtime="2016-04-1316:40:13"author="APP"id="140"title="什么是公告"content="公告,是公开宣告。"/>

  3. rowpubtime="2016-04-1316:36:50"author="网站"id="138"title="12345678"content="12345678"rowpubtime="2016-04-0615:02:44"author="网站"id="134"title="关于网站用户注册流程说明1"content="关于用户注册流程说明"rowpubtime="2016-03-3018:32:13"author="APP"id="126"title="关于网站使用说明"content="测试"rowpubtime="2016-03-3018:29:26"author="网站"id="125"title="关于手机App使用说明"content="123"</results>

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

Info类代码

收藏代码

  1. publicclassInfo{

  2. privateStringid;

  3. privateStringtitle;

  4. privateStringcontent;

  5. privateStringauthor;

  6. privateStringpubtime;

  7. publicStringgetId(){

  8. returnid;

  9. }

  10. publicvoidsetId(Stringid){

  11. this.id=id;

  12. }

  13. publicStringgetTitle(){

  14. returntitle;

  15. }

  16. publicvoidsetTitle(Stringtitle){

  17. this.title=title;

  18. }

  19. publicStringgetContent(){

  20. returncontent;

  21. }

  22. publicvoidsetContent(Stringcontent){

  23. this.content=content;

  24. }

  25. publicStringgetAuthor(){

  26. returnauthor;

  27. }

  28. publicvoidsetAuthor(Stringauthor){

  29. this.author=author;

  30. }

  31. publicStringgetPubtime(){

  32. returnpubtime;

  33. }

  34. publicvoidsetPubtime(Stringpubtime){

  35. this.pubtime=pubtime;

  36. }

  37. @Override

  38. publicStringtoString(){

  39. return"Info[author="+author+",content="+content+",id="+id

  40. +",pubtime="+pubtime+",title="+title+"]";

  41. }

  42. }

Row类代码

  • @XStreamConverter(RowConverter.class)

  • publicclassRowextendsHashMap<String,String>{

  • privatestaticfinallongserialVersionUID=5619951409573339302L;

  • }下载

  • Results代码

  • @XStreamAlias("results")

  • publicclassResults{

  • @XStreamAlias("name")

  • @XStreamAsAttribute

  • privateStringname;

  • @XStreamImplicit(itemFieldName="row")

  • privateList<Row>rows;

  • publicStringgetName(){

  • returnname;

  • }

  • publicvoidsetName(Stringname){

  • this.name=name;

  • }

  • publicList<Row>getRows(){

  • returnrows;

  • }

  • publicvoidsetRows(List<Row>rows){

  • this.rows=rows;

  • }

  • }

  • Rowconverter类代码

  • publicclassRowConverterextendsAbstractCollectionConverter{

  • publicRowConverter(Mappermapper){

  • super(mapper);

  • //TODOAuto-generatedconstructorstub

  • }

  • @Override

  • publicbooleancanConvert(Classarg0){

  • //TODOAuto-generatedmethodstub

  • returnRow.class.equals(arg0);

  • }

  • 下载

  • @Override

  • publicvoidmarshal(Objectarg0,HierarchicalStreamWriterwriter,

  • MarshallingContextarg2){

  • //TODOAuto-generatedmethodstub

  • Rowmap=(Row)arg0;

  • for(Iteratoriterator=map.entrySet().iterator();iterator.hasNext();){

  • Map.Entryentry=(Map.Entry)iterator.next();

  • writer.addAttribute(entry.getKey().toString(),entry.getValue().toString());

  • }

  • }

  • @Override

  • publicObjectunmarshal(HierarchicalStreamReaderreader,

  • UnmarshallingContextcontext){

  • //TODOAuto-generatedmethodstub

  • Rowmap=newRow();

  • populateMap(reader,context,map);

  • returnmap;

  • }

  • protectedvoidpopulateMap(HierarchicalStreamReaderreader,UnmarshallingContextcontext,Rowmap){

  • Iterator<String>iterator=reader.getAttributeNames();

  • while(iterator.hasNext()){

  • Objectkey=iterator.next();

  • Stringvalue=reader.getAttribute((String)key);

  • map.put(key.toString(),value.toString());

  • }

  • }

  • }

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

    测试类下载

    Java代码

    收藏代码

    1. publicclassXstream{

    2. privatestaticStringxml;

    3. staticvoidmain(String[]args)throwsException{

    4. //初始化

    5. init();

    6. XStreamxstream=newXStream(newXppDriver(newXmlFriendlyReplacer("_-","_")));

    7. //解析xml文本

    8. xstream.processAnnotations(Results.class);

    9. Resultsresults=(Results)xstream.fromXML(xml);

    10. //将解析出来的Results类对象转化成list列表

    11. List<Info>list=createList(Info.class,results);

    12. for(inti=0;i<list.size();i++){

    13. //打印

    14. Infoinfo=list.get(i);

    15. System.out.println(info.toString());

    16. }

    17. }

    18. voidinit(){

    19. //初始化xml文本

    20. xml="<resultsname=\"list\"><rowpubtime=\"2016-04-1316:40:13\"author=\"APP\"id=\"140\"title=\"什么是公告\"content=\"公告,是公开宣告。\"/><rowpubtime=\"2016-04-1316:36:50\"author=\"网站\"id=\"138\"title=\"12345678\"content=\"12345678\"/><rowpubtime=\"2016-04-0615:02:44\"author=\"网站\"id=\"134\"title=\"关于网站用户注册流程说明1\"content=\"关于用户注册流程说明\"/><rowpubtime=\"2016-03-3018:32:13\"author=\"APP\"id=\"126\"title=\"关于网站使用说明\"content=\"测试\"/><rowpubtime=\"2016-03-3018:29:26\"author=\"网站\"id=\"125\"title=\"关于手机App使用说明\"content=\"123\"/></results>";

    21. }

    22. static<T>ListcreateList(Class<T>clz,Resultsresults)throwsException{

    23. Listlist=newArrayList();

    24. for(Rowrow:results.getRows()){

    25. //根据class和Row生成对象放入list

    26. list.add(createObject(clz,row));

    27. }

    28. returnlist;

    29. }

    30. static<T>TcreateObject(Class<T>clazz,Rowrow)//初始化对象

    31. Tobj=clazz.newInstance();

    32. //遍历Info类中所有方法

    33. for(Methodmethod:clazz.getDeclaredMethods()){

    34. StringmethodName=method.getName();

    35. Class[]perams=method.getParameterTypes();

    36. //找到set开头,长度大于3,并且入参数量为1的方法

    37. if(methodName.startsWith("set")&&methodName.length()>3&&perams.length==1){

    38. Stringtemp=methodName.substring(3,methodName.length());

    39. //拿到属性名称

    40. StringfieldName=temp.toLowerCase();

    41. //根据属性名称从HashMap中拿到对应的值

    42. Stringvalue=row.get(fieldName);

    43. if(value!=null){

    44. //拿到该方法入参的Class,根据入参类型来决定调用方法形式

    45. ClassparamClass=perams[0];

    46. if(String.class.equals(paramClass)){

    47. method.invoke(obj,value);

    48. }elseif(Integer.class.equals(paramClass)||int.}if(Long.long.class.equals(paramClass)){下载

    49. method.invoke(obj,Long.valueOf(value));

    50. }if(BigDecimal.newBigDecimal(value));

    51. }if(Boolean.boolean.class.equals(paramClass)){

    52. if(value.equals("true")||value.equals("TRUE"))

    53. method.invoke(obj,85);font-weight:bold;">true);

    54. if(value.equals("false")||value.equals("FALSE"))

    55. method.invoke(obj,85);font-weight:bold;">false);

    56. }

    57. }

    58. }

    59. }

    60. returnobj;

    61. }

    62. }

    最后是输出效果:

    Java代码

  • Info[author=APP,content=公告,是公开宣告。,id=140,pubtime=2016-04-1316:40:13,title=什么是公告]

  • Info[author=网站,content=12345678,0);">138,0);">36:50,title=12345678]

  • Info[author=网站,content=关于用户注册流程说明,0);">134,0);">0615:02:44,title=关于网站用户注册流程说明1]

  • Info[author=APP,content=测试,0);">126,0);">03-3018:32:Info[author=网站,0);">123,0);">125,0);">29:26,title=关于手机App使用说明]

  • 版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐


    php输出xml格式字符串
    J2ME Mobile 3D入门教程系列文章之一
    XML轻松学习手册
    XML入门的常见问题(一)
    XML入门的常见问题(三)
    XML轻松学习手册(2)XML概念
    xml文件介绍及使用
    xml编程(一)-xml语法
    XML文件结构和基本语法
    第2章 包装类
    XML入门的常见问题(二)
    Java对象的强、软、弱和虚引用
    JS解析XML文件和XML字符串详解
    java中枚举的详细使用介绍
    了解Xml格式
    XML入门的常见问题(四)
    深入SQLite多线程的使用总结详解
    PlayFramework完整实现一个APP(一)
    XML和YAML的使用方法
    XML轻松学习总节篇