2016-10-11 49 views
0

删除空白我正在接收麻烦JSON一个Groovy过程具有属性/字段名含有空格:递归从JSON字段名在Groovy

{ 
    "leg bone" : false, 
    "connected to the" : { 
     "arm bones " : [ 
      { 
       " fizz" : "buzz", 
       "well hello" : "there" 
      } 
     ] 
    } 
} 

上面,领域,如"leg bone""well hello"期间导致问题处理(尽管它们在技术上是合法的JSON字段)。所以我想在传入的JSON中扫描每个字段(递归或嵌套方式),并用下划线(“_”)替换任何空格。因此,上述JSON将被转换成:

{ 
    "leg_bone" : false, 
    "connected_to__the" : { 
     "arm_bones_" : [ 
      { 
       "_fizz" : "buzz", 
       "well_hello" : "there" 
      } 
     ] 
    } 
} 

通常我用一个JsonSlurper解析JSON字符串成地图,但我似乎无法弄清楚如何得到正确的递归。这里是到目前为止我最好的尝试:

// In reality 'incomingJson' isn't hardcoded as a string literal, but this helps make my actual use case 
// an SSCCE. 
class JsonMapExperiments { 
    static void main(String[] args) { 
     String incomingJson = """ 
     { 
      "leg bone" : false, 
      "connected to the" : { 
       "arm bones " : [ 
        { 
         " fizz" : "buzz", 
         "well hello" : "there" 
        } 
       ] 
      } 
     } 
     """ 
     String fixedJson = fixWhitespaces(new JsonSlurper().parseText(incomingJson)) 
     println fixedJson 
    } 

    static String fixWhitespaces(def jsonMap) { 
     def fixedMap = [:] 
     String regex = "" 
     jsonMap.each { key, value -> 
      String fixedKey = key.replaceAll('\\s+', '_') 
      String fixedValue 
      if(value in Map) { 
       fixedValue = fixWhitespaces(value) 
      } else { 
       fixedValue = value 
      } 

      fixedMap[fixedKey] = fixedValue 
     } 

     new JsonBuilder(fixedMap).toString() 
    } 

} 

当这个运行时,最终输出是:

{"connected_to_the":"{\"arm_bones_\":\"[{ fizz=buzz, well hello=there}]\"}","leg_bone":"false"} 

这是有点儿/八九不离十接近,但不正是我需要的。有任何想法吗?

+1

你需要修复数组内容以及... –

+0

Yep @ammoQ(+1) - 你是对的!我猜想我认为'JsonSlurper'会以某种方式将JSON中的集合/列表/数组转换为映射。 – smeeb

+0

是空格问题,因为使用点符号时遇到问题?如果是这样,你也可以写:'jsonMap.'leg bone'' – Batsu

回答

1

鉴于你输入这个脚本:

def fixWhitespacesInTree(def tree) { 
    switch (tree) { 
     case Map: 
      return tree.collectEntries { k, v -> 
       [(k.replaceAll('\\s+', '_')):fixWhitespacesInTree(v)] 
      } 
     case Collection: 
      return tree.collect { e -> fixWhitespacesInTree(e) } 
     default : 
      return tree 
    } 
} 

def fixWhitespacesInJson(def jsonString) { 
    def tree = new JsonSlurper().parseText(jsonString) 
    def fixedTree = fixWhitespacesInTree(tree) 
    new JsonBuilder(fixedTree).toString() 
} 


println fixWhitespacesInJson(json) 

我得到以下结果:

{"connected_to_the":{"arm_bones_":[{"_fizz":"buzz","well_hello":"there"}]},"leg_bone":false} 

我会,但是,建议您更改正则表达式\\s+只是\\s。在前一种情况下。如果您在同一级别有两个JSON属性,一个名为" fizz",另一个名为" fizz",则翻译后的密钥将都是"_fizz",并且一个将在最终结果中覆盖另一个。在后一种情况下,翻译密钥将分别为"_fizz""__fizz",原始内容将被保留。