如何在我的示例中 groovy (java) 自动检测 json 字段类型?
How in my example in groovy (java) to automatically detect the json field type?
在我的任务中,我处理传入的 json 并使用 ResultSetReader 将数据 return 作为数据集。所有类型都必须写入“类型”。它们现在定义如下:def types = list.find (). Values () *. GetClass () *. SimpleName
但是这里有两个问题:
如果在json的第一个块中某个字段有“null”,而在下一个块中有一个数字,则类型写为“null”,而不是作为“整数”。
如果在所有json块中某人的字段是“null”,则写“null”,需要写,比如默认写“String”,这样程序不会停止工作。
我应该怎么做?恳请您不要重写我所有的代码,但要专门针对这个问题提出建议。 “类型”应仅包含格式为 ["String", "Integer", "String"] 的类型(例如)。
无需告知 in types 的位置 [NameJSON: String, NameJSON: Integer, NameJSON: Sting],因为在这种情况下我无法使用 ResultSetReader。
import groovy.json.JsonSlurper
import ru.itrpro.xm.plugins.groovy.ResultSetReader;
class XM_PARSE_XLS {
def execute(ResultSetReader reader, String pfile) {
def jsonSlurper = new JsonSlurper()
def list = jsonSlurper.parseText pfile
List names = list.inject( new LinkedHashSet<>() ){ res, map ->
res.addAll map.keySet()
res
}.toList()
def types = list.find().values()*.getClass()*.simpleName
//formation of the dataset header
reader.outputLinesSetHeaders(names,types);
list.each{ e ->
reader.outputLines names.collect{ e[ it ] }
//println names.collect{ e[ it ] }
}
//closing dataset
reader.outputLinesEnd();
return null;
}
static void main(String... args) {
String pfile = """
[{"AUTO":"bmw",
"HOME":null,
"JOB":""},
{"AUTO":"audi",
"HOME":135,
"JOB":null},
{"AUTO":"opel1",
"HOME":10,
"JOB":null}]
"""
def SSC = new XM_PARSE_XLS()
def res = SSC.execute(new ResultSetReader(), pfile)
}
}
工作示例here。
考虑更换这个:
def types = list.find().values()*.getClass()*.simpleName
有了这个(编辑: 针对关于 BigDecimal/double 的评论中的问题进行了更新):
// as requested in comments:
def getTypeDef(def value) {
(value instanceof BigDecimal) ? "double" : value.getClass().simpleName
}
def typeMap = [:].withDefault { key -> "String" }
list.each { map ->
map.each { key, value ->
if (value != null) {
typeMap[key] = getTypeDef(value)
}
}
}
def types = names.collect { name -> typeMap[name] }
这个想法是 typeMap
将字段名映射到它的类型,并且默认为 String
。那么:
- 遍历列表中的每个项目
- 迭代项目中的每个字段
- 如果字段已定义,请使用其在
typeMap
中的类型
如果任何项目的某个字段具有适当的值,则将使用该值(假设项目不能具有不同类型的值)。如果没有项目具有该字段的值,则 typeMap
将默认为 String
。
在我的任务中,我处理传入的 json 并使用 ResultSetReader 将数据 return 作为数据集。所有类型都必须写入“类型”。它们现在定义如下:def types = list.find (). Values () *. GetClass () *. SimpleName
但是这里有两个问题:
如果在json的第一个块中某个字段有“null”,而在下一个块中有一个数字,则类型写为“null”,而不是作为“整数”。
如果在所有json块中某人的字段是“null”,则写“null”,需要写,比如默认写“String”,这样程序不会停止工作。
我应该怎么做?恳请您不要重写我所有的代码,但要专门针对这个问题提出建议。 “类型”应仅包含格式为 ["String", "Integer", "String"] 的类型(例如)。
无需告知 in types 的位置 [NameJSON: String, NameJSON: Integer, NameJSON: Sting],因为在这种情况下我无法使用 ResultSetReader。
import groovy.json.JsonSlurper
import ru.itrpro.xm.plugins.groovy.ResultSetReader;
class XM_PARSE_XLS {
def execute(ResultSetReader reader, String pfile) {
def jsonSlurper = new JsonSlurper()
def list = jsonSlurper.parseText pfile
List names = list.inject( new LinkedHashSet<>() ){ res, map ->
res.addAll map.keySet()
res
}.toList()
def types = list.find().values()*.getClass()*.simpleName
//formation of the dataset header
reader.outputLinesSetHeaders(names,types);
list.each{ e ->
reader.outputLines names.collect{ e[ it ] }
//println names.collect{ e[ it ] }
}
//closing dataset
reader.outputLinesEnd();
return null;
}
static void main(String... args) {
String pfile = """
[{"AUTO":"bmw",
"HOME":null,
"JOB":""},
{"AUTO":"audi",
"HOME":135,
"JOB":null},
{"AUTO":"opel1",
"HOME":10,
"JOB":null}]
"""
def SSC = new XM_PARSE_XLS()
def res = SSC.execute(new ResultSetReader(), pfile)
}
}
工作示例here。
考虑更换这个:
def types = list.find().values()*.getClass()*.simpleName
有了这个(编辑: 针对关于 BigDecimal/double 的评论中的问题进行了更新):
// as requested in comments:
def getTypeDef(def value) {
(value instanceof BigDecimal) ? "double" : value.getClass().simpleName
}
def typeMap = [:].withDefault { key -> "String" }
list.each { map ->
map.each { key, value ->
if (value != null) {
typeMap[key] = getTypeDef(value)
}
}
}
def types = names.collect { name -> typeMap[name] }
这个想法是 typeMap
将字段名映射到它的类型,并且默认为 String
。那么:
- 遍历列表中的每个项目
- 迭代项目中的每个字段
- 如果字段已定义,请使用其在
typeMap
中的类型
如果任何项目的某个字段具有适当的值,则将使用该值(假设项目不能具有不同类型的值)。如果没有项目具有该字段的值,则 typeMap
将默认为 String
。