0

我有兴趣找到 JSON 的最里面的键。例如,如果我有以下 JSON :

{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
    "id": {
        "description": "The unique identifier for a product",
        "type": "integer"
    },
    "name": {
        "description": "Name of the product",
        "type": "string"
    },
    "price": {

        "minimum": 0,
    "type": "number",
        "exclusiveMinimum": true
    }
},
"required": ["id", "name", "price"]
}

然后输出应该有:descriptiontypedescriptiontypeminimumtypeexclusiveMinimum作为最里面的键。

4

2 回答 2

0

远非好,但看起来它有效,请尝试 Javascript 示例http://jsfiddle.net/3UMx5/2/

PS:对不起我的英语

用法

 var data = {
     "$schema": "http://json-schema.org/draft-04/schema#",
     "title": "Product",
     "description": "A product from Acme's catalog",
     "type": "object",
     "todo": {
         "level1": {
             "level2": {
                 "level3": {
                     "key": "here"
                 }
             }
         }
     },
     "properties": {
         "id": {
             "description": "The unique identifier for a product",
             "type": "integer"
         },
         "name": {
             "description": "Name of the product",
             "type": "dwq"
         },
         "price": {
             "minimum": 0,
             "type": "number",
             "exclusiveMinimum": true
         }
     },
     "required": ["id", "name", "price"]
 }

 searchInnermost(data);

Javascript

function searchInnermost(data){
    //convert json to string
    var jsonString = JSON.stringify(data);
    //split json string into chars
    var chars      = jsonString.split('');

    var mostInnerChars = getInnerMostChars(chars);
    var mostInnerJson  = restoreJsonFromChars(mostInnerChars);

    var keys = getKeysOnly(mostInnerJson)
    return keys;
}

function getInnerMostChars(chars){
    var level      = 0;
    var maxLevel   = level;
    var items      = [];

    //loop throught each char
    for(var i = 0; i < chars.length; i++){
        //TODO more accurate identifier needed, if { -> deeper level, level increased
        if(chars[i] == '{'){
            level++;
            if(level > maxLevel){
                maxLevel = level;
            }
        }        

        //store each char in levels array
        if(!items[level]){
            items[level] = [];
        }

        items[level].push(chars[i]);

        //if } -> level reduced
        if(chars[i] == '}'){
            level--;
        }
    }

    return items[maxLevel];
}
//restore json string
function restoreJsonFromChars(chars){
    var restored = chars.join('').replace(/\}\{/g, '},{');
    restored = '[' + restored + ']';
    return JSON.parse(restored);
}
//get json keys
function getKeysOnly(json){
    var keysOnly = [];
    for(var i = 0; i < json.length; i++){
        for(var key in json[i]){
            keysOnly.push(key);
        }
    }

    return keysOnly;
}
于 2013-09-06T07:19:56.810 回答
0

更简单的方法:
第一个函数查找所有属性及其级别

function findAllProperties(obj)
{
   var retVal = [];
   (function findProperty(obj, depth)
   {
       for (var prop in obj)
       {
           if (obj[prop] instanceof Object)
           {
              findProperty(obj[prop], depth + 1); 
           }
           else
           {
              retVal.push({"name" : prop, "depth" : depth}); 
           }
       }
   })(obj, 0);
   return retVal;
} 

第二个函数查找具有最高级别的属性

function siftInnerMost(items)
{
    var maxDepth = 0, retVal = [];
    for (var i in items)
    {
        if (items[i].depth == maxDepth)
        {
           retVal.push(items[i].name);
        }
        else if (items[i].depth > maxDepth)
        {
           maxDepth = items[i].depth;
           retVal = [items[i].name];
        }
    }
    return retVal;
}  

现在你可以找到inner most钥匙

var inners = findAllProperties(data);
var innerMost = siftInnerMost(inners);  

JSFiddle 演示

带有Json-Simple库 的Java解决方案

public class InnerMostFinder 
{
   private List<Pair> inners = new ArrayList<Pair>();

    private static class Pair
    {
       int level;
       String property;

       public Pair(int level, String property) 
       {
          this.level = level;
         this.property = property;
       }
    }

    private void findAllProperties(final JSONObject obj, final int level)
    {
       for (Object key : obj.keySet())
       {
          Object innerObj = obj.get(key);
          if (innerObj instanceof JSONObject)
          {
             findAllProperties((JSONObject) innerObj, level + 1); 

          }
          else
          {
              inners.add(new Pair(level, (String) key)); 
          }
       }
    }

    public List<String> getInnerMost(final JSONObject obj)
    {
       final List<String> retVal = new ArrayList<String>();
       int maxLevel = 0;
       findAllProperties(obj, maxLevel);
       for (final Pair pair : inners)
       {
          if (pair.level == maxLevel)
          {
             retVal.add(pair.property);
          }
          else if (pair.level > maxLevel)
          {
             maxLevel = pair.level;
             retVal.clear();
             retVal.add(pair.property);
          }
       }
       return retVal;
    }
}  

用法

   JSONObject obj = (JSONObject) new JSONParser()
      .parse(new FileReader(new File("D:/test.json")));
   System.out.println(new InnerMostFinder().getInnerMost(obj));
于 2013-09-06T08:21:57.367 回答