码迷,mamicode.com
首页 > 编程语言 > 详细

xml转json的递归算法

时间:2015-07-27 18:22:58      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

  之前找了一个json-lib的bug,里面展示了一段遍历xml并将其转换为json的算法,今天就来说说这个算法,这个算法所用到的东西就是所谓的递归算法,虽然在程序中不建议用递归算法。

   递归算法的特点:

      1.递归就是在过程或函数里调用自身

      2. 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。

      如果不满足第一点就不叫递归,如果不满足第二点,那么将会永无结束条件,直到崩溃。有人说盗梦空间就是一个递归,每一层梦境就是一层递归,然后每一层时间就比上一层慢20倍,盗梦空间要结束的条件就是duang一下(坠击)

然后,再说说高人给我说的写递归算法的方法:

    不要对运行机制深究,就是每一步怎么运行的,不然你会被递归进去,你要做的是把这一层可能的所有情况考虑清楚就行了,如果这一层情况考虑完了不知道怎么处理的时候,交给下一层处理,如果这一层可能的情况没有考虑完,那么就等着程序报错,再来找,还有考虑的时候从结束条件开始考虑,然后考虑最简单的情况。

    下面是测试的xml:

    

技术分享
 1  <ll:entitys> 
 2     <ll:filter dbfiled="name|id|age" dbtable="emp|mgr|account"/>  
 3     <ll:package package="author.liulang.mgr.mod.entity"/>  
 4     <ll:parent cls="author.liulang.mgr.mod.inter.ModAdaptor"/>  
 5     <ll:save path="author/liulang/mgr/mod/entity/"/>  
 6     <ll:attr public="public" serial="yes" filed="private" static="no" getter="public" setter="public" tostring="public" equals="public" hashcode="public"/>  
 7     <ll:types> 
 8       <ll:type db="int" java="int"/>  
 9       <ll:type db="intunsigned" java="int"/>  
10       <ll:type db="integer" java="int"/>  
11       <ll:type db="char" java="String"/>  
12       <ll:type db="tinyint" java="int"/>  
13       <ll:type db="bigint" java="long"/>  
14       <ll:type db="date" java="java.util.Date"/>  
15       <ll:type db="datetime" java="java.util.Date"/>  
16       <ll:type db="varchar" java="String"/>  
17       <ll:type db="double" java="double"/>  
18       <ll:type db="decimal" java="java.math.BigDecimal"/>  
19       <ll:type db="float" java="float"/>  
20       <ll:type db="text" java="String"/>  
21       <ll:type db="int" java="int"/> 
22     </ll:types> 
23   </ll:entitys> 
xml Code

 

    下面是最简单的加法递归算法:

技术分享
 1 public class Test {
 2     /**
 3      * 从1+n的递归算法
 4      * @param n
 5      * @return
 6      */
 7     public static int add(int n){
 8          /*
 9           * n的情况一:可能是0,如果是0就该结束了
10           */
11         if (n==0) {
12             return 0;
13         }
14         /*
15          * 情况二:n不是0,那么n-1之前所有的数之和
16          * 与自己相加,就是n的结果了,至于add方法怎么
17          * 加的我不知道,不陷入进去了
18          */
19         return n+add(n-1);
20     }
21     public static void main(String[] args) {
22         System.err.println(add(100));
23     }
24 }
add Code

好的,现在讲一下我那个xml序列化成json的算法:

首先,我们xml都是由一个一个节点组成的,而节点的开始 ,我们称之为元素,总的来说xml由节点,由属性,由文本这三部分组成,那么结束条件就是当这个元素没有了文本,没有了属性,没有子元素,三个条件同时满足,就该结束了。

一、找结束条件:

技术分享
 1    public  static JSONObject xmlToJson(Element e){
 2       /*建立一个对象,返回json,我们目的是转换为json对象,所以返回的一定是     json格式 ,所以即使有数组的情况也不用去考虑*/
 3       JSONObject json=new JSONObject();
 4        /*查看是否有文本数据,有就放入到text字段中,没有就直接跳过,成为结束条件之一*/
 5        String text=e.getTextTrim();
 6        if (text.length()!=0) {
 7            json.put("text",text);
 8         }
 9        /*查看元素是否有属性,有就放入到json中,以属性名作为字段,属性值作为value,没有就是结束条件之一,直接略过*/
10        @SuppressWarnings("unchecked")
11         List<Attribute> attrs=e.attributes();
12        for (Attribute attr : attrs) {
13             json.put(attr.getName(),attr.getValue());
14         }
15 
16        return json;
17 }
end condition

上面,把没有文本和没有属性的结束条件列举出来了,下面列举没有子元素的结束条件

技术分享
 1    public  static JSONObject xmlToJso(Element e){
 2        JSONObject json=new JSONObject();
 3        //查看是否有文本数据
 4        String text=e.getTextTrim();
 5        if (text.length()!=0) {
 6            json.put(R.S.TEXT,text);
 7         }
 8        //查看元素是否有属性
 9        @SuppressWarnings("unchecked")
10         List<Attribute> attrs=e.attributes();
11        for (Attribute attr : attrs) {
12             json.put(attr.getName(),attr.getValue());
13         }
14        //查看元素是否包含元素
15        @SuppressWarnings("unchecked")
16         List<Element> es=e.elements();
17        for (Element ele : es) {/*如果es的size为零,将不会进入迭代for循环,那么此时就是结束条件的满足*/
18         }
19        return json;
20 }
element Code

当然,假如子元素不为零,这个程序就应该继续进行下去,但是怎么继续呢?如果子元素不为零,那么可能出现两种情况,第一种:子元素都是不同的,还有种就是子元素可能存在相同的.

那么:都是不同的,我们可以就用普通json存放,有多个相同的我们可以用数组存放。

代码:

技术分享
   public  static JSONObject xmlToJso(Element e){
       JSONObject json=new JSONObject();
       //查看是否有文本数据
       String text=e.getTextTrim();
       if (text.length()!=0) {
           json.put(R.S.TEXT,text);
        }
       //查看元素是否有属性
       @SuppressWarnings("unchecked")
        List<Attribute> attrs=e.attributes();
       for (Attribute attr : attrs) {
            json.put(attr.getName(),attr.getValue());
        }
       //查看元素是否包含元素
       @SuppressWarnings("unchecked")
        List<Element> es=e.elements();
       for (Element ele : es) {
             @SuppressWarnings("unchecked")
            List<Element> elecount=e.elements(ele.getQName());
           //说明该元素是唯一的,不做数组处理
             if (elecount.size()==1) {
                                 /*子元素是当前元素的一个重复,所以这里不知道怎么做的交给了下一层*/
                    json.put(ele.getName(),xmlToJson(ele));
             }
             //说明该元素不是唯一的,应该以数组处理
             if (elecount.size()>1) {
                JSONArray arr=new JSONArray();
                String key=null;
                for (Element el: elecount) {
                    if (key==null) {
                        key=el.getName();
                    }
                               /**将每个元素的结果放入数组,然后统一放回返回的json中,每个元素仍然是本层的重复,就调用自身了*/
                    arr.add(xmlToJson(el));
                }
                json.put(key,arr);
            }
        }
       return json;
}
View Code

好了,这个程序,貌似好像,基本,应该写完了。运行一下:

{
    "filter": {
        "dbfiled": "name|age",
        "dbtable": ""
    },
    "package": {
        "package": "author.liulang.mgr.mod.entity"
    },
    "parent": {
        "cls": "author.liulang.mgr.mod.inter.ModAdaptor"
    },
    "save": {
        "path": "author/liulang/mgr/mod/entity/"
    },
    "attr": {
        "public": "public",
        "serial": "no",
        "filed": "private",
        "static": "yes",
        "getter": "public",
        "setter": "public",
        "tostring": "public",
        "equals": "none",
        "hashcode": "none"
    },
    "types": {
        "type": [
            {
                "db": "int",
                "java": "int"
            },
            {
                "db": "intunsigned",
                "java": "int"
            },
            {
                "db": "integer",
                "java": "int"
            },
            {
                "db": "char",
                "java": "String"
            },
            {
                "db": "tinyint",
                "java": "int"
            },
            {
                "db": "bigint",
                "java": "long"
            },
            {
                "db": "date",
                "java": "java.util.Date"
            },
            {
                "db": "datetime",
                "java": "java.util.Date"
            },
            {
                "db": "varchar",
                "java": "String"
            },
            {
                "db": "double",
                "java": "double"
            },
            {
                "db": "decimal",
                "java": "java.math.BigDecimal"
            },
            {
                "db": "float",
                "java": "float"
            },
            {
                "db": "text",
                "java": "String"
            }
        ]
    }
}

好像,貌似,真的,应该没有问题了,绝对?绝对?没有问题了?

额:结果真的是没有什么问题了,反正我是没有测出来什么问题,可是我在调试的时候确发现了一个问题,效率问题,其实我们发现一个type元素就得递归一次,n个type元素就得递归n次,只是因为在json里面存放的key相同,前面递归出来的数据被后一条代替了:

    /**
     * 迭代某元素,属性,文本,及下级元素,并将其转换为json对象
     */
  public  static JSONObject xmlToJson(Element e){
            JSONObject json=new JSONObject();
            //查看是否有文本数据
            String text=e.getTextTrim();
            if (text.length()!=0) {
                json.put("text",text);
            }
            //查看元素是否有属性
            @SuppressWarnings("unchecked")
            List<Attribute> attrs=e.attributes();
            for (Attribute attr : attrs) {
                json.put(attr.getName(),attr.getValue());
            }
            //查看元素是否包含元素
            @SuppressWarnings("unchecked")
            List<Element> es=e.elements();
            for (Element ele : es) {
                 @SuppressWarnings("unchecked")
                List<Element> elecount=e.elements(ele.getQName());
               //说明该元素是唯一的,不做数组处理
                 if (elecount.size()==1) {
                        json.put(ele.getName(),xmlToJso(ele));
                 }
                 //说明该元素不是唯一的,应该以数组处理
                 if (elecount.size()>1) {
                    JSONArray arr=new JSONArray();
                    String key=null;
                    for (Element el: elecount) {
                        if (key==null) {
                            key=el.getName();
                        }
                        arr.add(xmlToJso(el));
                    }
                               /*这里一条调试输出语句*/
                    System.err.println(arr);
                    json.put(key,arr);
                }
            }
            return json;
  }

输出结果:

 1 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
 2 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
 3 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
 4 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
 5 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
 6 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
 7 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
 8 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
 9 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
10 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
11 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
12 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]
13 [{"db":"int","java":"int"},{"db":"intunsigned","java":"int"},{"db":"integer","java":"int"},{"db":"char","java":"String"},{"db":"tinyint","java":"int"},{"db":"bigint","java":"long"},{"db":"date","java":"java.util.Date"},{"db":"datetime","java":"java.util.Date"},{"db":"varchar","java":"String"},{"db":"double","java":"double"},{"db":"decimal","java":"java.math.BigDecimal"},{"db":"float","java":"float"},{"db":"text","java":"String"}]

可以看到重复输出了13次,就是每一个type元素都要序列化一次,效率代价挺大,所以我们这段代码还得加一个限制条条件,只需要重复一次就可以了

        public static JSONObject xmlToJson(Element e){      
      JSONObject json=new JSONObject();         
  //查看是否有文本数
 
          String text=e.getTextTrim();

if (text.length()!=0) { json.put(R.S.TEXT,text); } //查看元素是否有属性 @SuppressWarnings("unchecked") List<Attribute> attrs=e.attributes(); for (Attribute attr : attrs) { json.put(attr.getName(),attr.getValue()); } //查看元素是否包含元素 @SuppressWarnings("unchecked") List<Element> es=e.elements(); for (Element ele : es) { @SuppressWarnings("unchecked") List<Element> elecount=e.elements(ele.getQName()); //说明该元素是唯一的,不做数组处理 if (elecount.size()==1) { json.put(ele.getName(),xmlToJson(ele)); } //说明该元素不是唯一的,应该以数组处理 if (elecount.size()>1) { /*之前已经遍历过了,此次不需要再遍历,
注意这个限制条件只能是continue不能是break,
因为break了,就将整个循环给跳了出去,如果type之后还有其他元素,
将遍历不到,而continue只是当次不再循环*/
if (elecount.indexOf(ele)>0) { continue; } JSONArray arr=new JSONArray(); String key=null; for (Element el: elecount) { if (key==null) { key=el.getName(); } arr.add(xmlToJson(el)); } json.put(key,arr); } } return json; }

好了,序列化的递归算法基本写完了,只能是说基本,因为可能某些特殊操作还会出现bug,这只能遇到了才改

 

 

 

   

 

xml转json的递归算法

标签:

原文地址:http://www.cnblogs.com/liulangdege/p/4665591.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!