这是一个jolt 使用教程的项目
Jolt是用Java编写的JSON到JSON转换库,可以将我们输入的一个json,转换成目标json.
jolt官网传送门 官网地址.
详细使用教程可以访问本人如下开源项目
github jolt教程 开源项目 jolt-universe.
gitCode jolt 教程 开源项目 jolt-universe
gitee 码云 jot教程 开源项目 jolt-universe.
开源项目会持续更新,为大家带来更全、更好的jolt用法教程,如果大家有什么疑问,或者有什么需要转换json,可以在issues 中注明 input(输入),和Output(输出),
大家可以一起探讨交流。
文中如有描述错误,请及时留言指出。如有转载,请标明出处。
在线调试工具
在线调试工具 传送门地址.
你可以将json数据和jolt表达式在上面运行,由于这个在线工具是托管在 Google App Engine 上面的,国内的网络可能无法访问
入门教程
快速入门
1在maven中添加 jolt的依赖
<dependency>
<groupId>com.bazaarvoice.jolt</groupId>
<artifactId>jolt-core</artifactId>
<version>0.1.6</version>
</dependency>
<dependency>
<groupId>com.bazaarvoice.jolt</groupId>
<artifactId>json-utils</artifactId>
<version>0.1.6</version>
</dependency>
目前最新的版本为0.1.6 具体的版本号可以查看这里 jolt历史版本.
以下是具体的demo ShiftTest.java
演示demo
package com.example.demo.shift;
import com.bazaarvoice.jolt.Chainr;
import com.bazaarvoice.jolt.JsonUtils;
import org.junit.jupiter.api.Test;
import java.util.List;
public class ShiftTest {
/**
* 测试demo
*/
@Test
public void testDemo() {
//将json字符串转成object 对象
Object input = JsonUtils.classpathToObject("/json/sample/input.json");
//将json字符串转成List 对象
List spec = JsonUtils.classpathToList("/json/sample/spec.json");
Chainr chainr = Chainr.fromSpec(spec);
//转换结果
Object transform = chainr.transform(input);
System.out.println(JsonUtils.toJsonString(transform));
}
}
/json/sample/input.json
数据json文件
{
"orderId": 1212,
"orderNo":"202223434343",
"goods": {
"goodsId": 123,
"goodsName": "test_goods"
},
"orderItem": [{
"orderItemId": 1324,
"orderItemNo": "34535345"
}]
}
/json/sample/spec.json
表达式json文件
[{
"operation": "shift",
"spec": {
"orderId": "data.order_id",
"orderNo": "data.order_no",
"orderItem": {
"*": {
"orderItemId": "data.order_item.[#2].order_item_id",
"orderItemNo": "data.order_item.[#2].order_item_no"
}
}
}
},
{
"operation": "default",
"spec": {
"Range": 5,
"data": {
"default": 12345
}
}
}
]
输出结果:
{
"data" : {
"order_id" : 1212,
"order_no" : "202223434343",
"order_item" : [ {
"order_item_id" : 1324,
"order_item_no" : "34535345"
} ],
"default" : 12345
},
"Range" : 5
}
jolt的不同模式和用法
shift : 将输入json复制到输出json
default : 为输出的json树中增加默认值
remove : 从json树中去除指定的key
sort : 按字母顺序排序映射键值
cardinality : 修正输入数据的基数。urls元素通常是一个List,但是如果只有一个,那么它就是一个字符串
modify-overwrite-beta:总是写
modify-default-beta:当键值对应的值是null时写入
modify-define-beta:当键值不存在时写入
自定义Java类全路径名称:实现Transform或ContextualTransform接口,可选择SpecDriven接口
上面的模式是可以互相结合使用的,下文会详细讲解
以上的说明借鉴了"Panda诚博客" 博客的内容,下面有给出博主的博客地址
上面的前5种类型都只对json的结构进行转换,如果需要对数据进行操作则需要用到modify等相关操作
这里也给大家推荐一下,同样分享jolt的博主 Panda诚博客 传送门.
下面我会给大家详细说明以上不同模式的用法和一些样例。
shift模式的详细例子
shift 模式的作用的将一个input 的json 转成 expected的json,只改变数据结构,不对数据进行操作
简单的格式转换
input 输入:
{
"order": {
"orderItem": {
"id": 3,
"num": 5
}
}
}
expected 预期输出:
{
"orderForm": {
"orderDetails": {
"id": 3,
"num": 5
}
}
}
jolt简单的表达式如下:
[
{
"operation": "shift",
"spec": {
"order": {
"orderItem": {
"id": "orderForm.orderDetails.id", // 将id 为3的值复制到 "orderForm.orderDetails.id"的路径上
"num": "orderForm.orderDetails.num" // 将num为 5的值复制到"orderForm.orderDetails.num"
}
}
}
}
]
shift模式中‘&’和‘*'的简单使用
'*'的用法和正则表达式中的类似,指的是模糊匹配,下面我们用具体的例子说明
input 输入:
{
"rating": {
"primary": {
"value": 3
},
"quality": {
"value": 3
}
}
}
expected 预期输出:
{
"SecondaryRatings" : {
"data_primary" : {
"val" : 3
},
"data_quality" : {
"val" : 3
}
}
}
jolt 表达式如下:
[
{
"operation": "shift",
"spec": {
"rating": {
"*": { //这里的‘*’匹配的是 input 中的 primary 和 quality
"value": "SecondaryRatings.data_&1.val" // &1匹配的就是 primary 或 quality
}
}
}
}
]
这里我们来讲解一下‘&’的用法比如上文的表达式,&1 指的意思就是“value”上一级的key,那“value”上一级的key
就是‘*’,又因为“*”匹配的是primary 和 quality,所以 &1取到的就是(primary 或 quality),同理 &2 取到的就是key “rating”
下面我们再用更多具体的例子,让大家更深入了解“&”的用法
下面为大家讲解如何利用将input 一个值赋值给两个key
input 输入:
{
"rating_primary_value": 3
}
expected 预期输出:
{
"key_primary" : 3,
"key_value" : 3
}
jolt 表达式,这里给大家演示两种方式
//方式1:
[
{
"operation": "shift",
"spec": {
//这里数组的意思是将 rating_primary_value 的值拷贝到数组元素的key中
"rating_primary_value": ["key_primary", "key_value"]
}
}
]
//方式2:
[
{
"operation": "shift",
"spec": {
// 第一个“*”号匹配的是"primary",第二的“*”匹配的是"value"
//&(0,1)指的是第一个“*”号匹配的值,&(0,2)指的是第二个星号匹配的值
"rating_*_*": ["key_&(0,1)", "key_&(0,2)"]
}
}
]
//上面这个例子 &0 和&(0,0)的效果是等价的匹配到的都是 “rating_primary_value” ,&(0,1)指的就是在 "rating_*_*" 中一个*号匹配的值"primary", 以此类推
// &1 和 &(1,0)匹配到的是 “root”,这个后面我们的源码中会讲解
shift模式中数组的转换和 ‘#’的使用
'#'的作用通常是用来转换数组的,下面我们用具体的例子讲解
input 输入:
{
"orderId": 1212,
"orderNo": "202223434343",
"orderItem": [
{
"orderItemId": 1,
"orderItemNo": "2022xxxxxx01",
"goods": [
{
"goodsId": 1,
"goodsNum": 5
},
{
"goodsId": 2,
"goodsNum": 6
}
]
},
{
"orderItemId": 2,
"orderItemNo": "2022xxxxxx02",
"goods": [
{
"goodsId": 3,
"goodsNum": 6
},
{
"goodsId": 4,
"goodsNum": 7
}
]
}
]
}
shift :
[{
"operation": "shift",
"spec": {
"orderId": "o_id",
"orderNo": "o_no",
"orderItem": {
"*": { // '*' 匹配的是orderItem数组的下标
"orderItemId": "o_item.[#2].o_item_id", // #2代表的是从orderItemId往上数的第二个key,也就是'orderItem',这就代表着 o_item数组对标 输入的 orderItem
"orderItemNo": "o_item.[#2].o_item_no",
"goods": {
"*": {
"goodsId": "o_item.[#4].o_goods.[#2].g_id", // 这里类似 [#4] 往上数4就是'orderItem',[#2]就是 'goods'
"goodsNum": "o_item.[#4].o_goods.[#2].g_num"
}
}
}
}
}
}]
输出:
{
"o_id": 1212,
"o_no": "202223434343",
"o_item": [
{
"o_item_id": 1,
"o_item_no": "2022xxxxxx01",
"o_goods": [
{
"g_id": 1,
"g_num": 5
},
{
"g_id": 2,
"g_num": 6
}
]
},
{
"o_item_id": 2,
"o_item_no": "2022xxxxxx02",
"o_goods": [
{
"g_id": 3,
"g_num": 6
},
{
"g_id": 4,
"g_num": 7
}
]
}
]
}
如果输入的json 是一个数组要怎么转换呢,请看下面的例子
input 输入:
[
{
"orderItemId": 1,
"orderItemNo": "2022xxxxxx01"
},
{
"orderItemId": 2,
"orderItemNo": "2022xxxxxx02"
}
]
预期输出:
[ {
"orderId" : 1,
"orderNo" : "2022xxxxxx01"
}, {
"orderId" : 2,
"orderNo" : "2022xxxxxx02"
} ]
spec 表达式:
[
{
"operation": "shift",
"spec": {
"*": {
"orderItemId": "[#2].orderId",
"orderItemNo": "[#2].orderNo"
}
}
}
]
其实除了使用‘#’进行数组的转换,还可以使用“&”来实现,比如上文的转换,也可以使用如下表达式
spec 表达式:
[
{
"operation": "shift",
"spec": {
"*": {
"orderItemId": "[&1].orderId",
"orderItemNo": "[&1].orderNo"
}
}
}
]
shift 模式也支持取出指定下标的元素
{
"order": [
{
"orderItemId": 1,
"orderItemNo": "2022xxxxxx01"
},
{
"orderItemId": 2,
"orderItemNo": "2022xxxxxx02"
}
]
}
取出下标为0的元素 spec:
[
{
"operation": "shift",
"spec": {
"order": {
"0": "order"
}
}
}
]
输出结果:
{
"order" : {
"orderItemId" : 1,
"orderItemNo" : "2022xxxxxx01"
}
}
‘&’转换数组和‘#’的区别在于[]里面的数值,‘&’ 比‘#’小1,
[&]对应的是下标,如上文 * 匹配的是下标 0或 1,[&1]只的就是对应的下标0或1
[#]要对应的是上层的key,如上文,[#2]对应的是key ‘root’,有小伙伴就会产生疑问这个‘root’是哪来的,input里面没有呀,别着急后续我们会在源码篇详细讲解
上面将的都是‘#’在LHS的用,下面我们将一下‘#’在 RHS变的用法,‘#’在RHS可以给输出key赋值指定字符串
{
"rating": "555",
"primary": "1234"
}
spec:
[
{
"operation": "shift",
"spec": {
"rating": "rating",
"primary": "primary",
"#666": "value" //给value 赋值 “666”
}
}
]
输出结果:
{
"value" : "666",
"rating" : "555",
"primary" : "1234"
}
基于上面的用法比较常用的转换就是枚举值的转换
假设我们这这样一个例子,输出一个sex 字段,1代表男,2代表女,我们需要把这个字段转换成SexEnum枚举类
package com.example.oxy.enums;
import lombok.Getter;
/**
* 性别枚举类
* @author oxy
*/
public enum SexEnum {
MAN("男", "man"),
WOMAN("女", "woman");
@Getter
private String desc;
@Getter
private String code;
SexEnum(String desc, String code) {
this.desc = desc;
this.code = code;
}
}
input 输入:
{
"name": "张三",
"sex": 1
}
shift:
[
{
"operation": "shift",
"spec": {
"name": "name",
"sex": {
"1": { //如果sex =1 ,将其转成男性枚举值
"#男": "sex.desc",
"#man": "sex.code"
},
"2": { //如果sex =2 ,将其转成女性枚举值
"#女": "sex.desc",
"#woman": "sex.code"
}
}
}
}
]
{
"name" : "张三",
"sex" : {
"desc" : "男",
"code" : "man"
}
}
shift模式中 ‘$’的使用
'$'的作用是将input中的key当做值,映射给输出的json key中,请看下面的例子
input 输入:
{
"rating": {
"primary": {
"value": 3
},
"quality": {
"value": 3
}
}
}
spec:
[
{
"operation": "shift",
"spec": {
"rating": {
"primary": {
"value": "Rating",
"max": "RatingRange"
},
"*": { //"*"匹配的是 quality
"$": "SecondaryRatings.Id" //"$"的意思是将“*”匹配的key 当做值赋值给 SecondaryRatings.Id
}
}
}
}
]
输出:
{
"Rating" : 3,
"SecondaryRatings" : {
"Id" : "quality"
}
}
shift模式中 ‘@’的使用
‘@’ LHS、RHS都有效,意义一样,可以取到数据树中指定的值,单独写@时是等价于@0的,下面我们有具体的例子来讲解
input 输入:
{
"rating": {
"primary": 111,
"quality": 222
},
"xxx": 4444
}
spec:
[
{
"operation": "shift",
"spec": {
"rating": {
"@": "yyy" //将@等价于@0,代表的是将 rating 的值赋值给yyy
}
}
}
]
输出:
{
"yyy" : {
"primary" : 111,
"quality" : 222
}
}
input 输入:
{
"rating": {
"primary": 111,
"quality": 222
},
"xxx": 4444
}
spec:
[
{
"operation": "shift",
"spec": {
"rating": {
"@primary": "yyy", //将@primary等价于@(0,primary),代表的是将 primary 的值赋值给yyy
"@quality": "aaa", //将@primary等价于@(0,quality),代表的是将 quality 的值赋值给aaa
"@(1,xxx)": "bbb", //@(1,xxx) 的1代表和rating同一个等级的xxx 的值赋值给 bbb
"primary": {
"@(2,xxx)": "ccc" //@(2,xxx)的2是'primary'指往上数2个等级的也就是和rating同一等级的xxx的值赋值给ccc
}
}
}
}
]
输出:
{
"yyy" : 111,
"aaa" : 222,
"bbb" : 4444,
"ccc" : 4444
}
'@'在RHS的使用例子
input 输入:
{
"rating": {
"primary": "orderKey",
"quality": "order"
}
}
spec:
[
{
"operation": "shift",
"spec": {
"rating": {
"@primary": "@quality" //将rating.primary的值赋值给 order,order是rating.quality的值
}
}
}
]
输出:
{
"order" : "orderKey"
}
default 模式的详细例子
default 的作用是给json赋默认值,如果对应的key不存在或值为null时,给其赋上默认值
简单的赋默认值
input 输入:
{
"rating": {
"primary": {
"value": 3
},
"quality": {
"value": 3
}
}
}
expected 预期输出:
{
"rating" : {
"primary" : {
"value" : 3,
"Range" : 5
},
"quality" : {
"value" : 3,
"Range" : 5
}
},
"Range" : 5
}
jolt简单的表达式如下:
[
{
"operation": "default",
"spec": {
"Range": 5,
"rating": {
"*": {//这是的星号匹配的是key "primary" 和 "quality"
// 给rating.primary.Range、rating.quality.Range赋默认值5
"Range": 5
}
}
}
}
]
default 默认是只能给不存在的key或key 为null的字段 赋默认值,如果对应的key已存在具体值default的配置则不会起效果
例子:
input 输入:
{
"default": null
}
jolt 表达式:
[
{
"operation": "default",
"spec": {
"Range": 5,
"default": 6
}
}
]
expected输出结果:
{
"default" : 6,
"Range" : 5
}
input 如果输入的结果是:
{
"default": 3
}
expected输出结果:
{
"default" : 3,
"Range" : 5
}
remove 模式的详细例子
remove 的作用是将json中不需要的key进行删除
简单的remove例子
input 输入:
{
"rating": {
"primary": {
"value": 3,
"id": 23
},
"quality": {
"value": 3,
"id": 24
}
}
}
spec :
[
{
"operation": "remove",
"spec": {
"rating": {
"primary": "", //删除 rating.primary
"quality": {
"id": "" //删除 rating.quality.id
}
}
}
}
]
expected 输出:
{
"rating" : {
"quality" : {
"value" : 3
}
}
}
cardinality 模式的详细例子
简单的cardinality例子
cardinality模式的作用是可以将单个数据包装成数组,或者取出数组中第一个元素
‘ONE’:如果输入值是一个列表,则获取该列表中的第一个元素,并将其设置为该元素的数据,不支持其他类型
‘MANY’:如果输入不是列表,则创建一个列表并将第一个元素设置为输入值。如果输入是"null",使它成为一个空列表。如果输入是一个列表,不支持。
input 输入:
{
"rating": {
"primary": [
{
"value": 3,
"id": 23
},
{
"value": 3,
"id": 23
}
],
"quality": {
"value": 5,
"id": 25
}
}
}
spec :
[
{
"operation": "cardinality",
"spec": {
"rating": {
"primary": "ONE", //取出 primary 中的一个元素
"quality": "MANY" //将 quality 转换成数组
}
}
}
]
expected 输出:
{
"rating": {
"primary": {
"value": 3,
"id": 23
},
"quality": [
{
"value": 5,
"id": 25
}
]
}
}
modify 模式的详细例子
modify相关案例讲解
modify又分成如下模式:
modify-overwrite-beta: 模式是对指定的key的数据进行操作,无法key是否存在或已存在值,始终会对其进行操作
default modify-default-beta :当键值对应的值是null时写入
define modify-define-beta :当键值不存在时写入
modify 模式包含如下函数:
private static final Map<String, Function> STOCK_FUNCTIONS = new HashMap<>( );
static {
STOCK_FUNCTIONS.put( "toLower", new Strings.toLowerCase() );
STOCK_FUNCTIONS.put( "toUpper", new Strings.toUpperCase() );
STOCK_FUNCTIONS.put( "concat", new Strings.concat() );
STOCK_FUNCTIONS.put( "join", new Strings.join() );
STOCK_FUNCTIONS.put( "split", new Strings.split() );
STOCK_FUNCTIONS.put( "substring", new Strings.substring() );
STOCK_FUNCTIONS.put( "trim", new Strings.trim() );
STOCK_FUNCTIONS.put( "leftPad", new Strings.leftPad() );
STOCK_FUNCTIONS.put( "rightPad", new Strings.rightPad() );
STOCK_FUNCTIONS.put( "min", new Math.min() );
STOCK_FUNCTIONS.put( "max", new Math.max() );
STOCK_FUNCTIONS.put( "abs", new Math.abs() );
STOCK_FUNCTIONS.put( "avg", new Math.avg() );
STOCK_FUNCTIONS.put( "intSum", new Math.intSum() );
STOCK_FUNCTIONS.put( "doubleSum", new Math.doubleSum() );
STOCK_FUNCTIONS.put( "longSum", new Math.longSum() );
STOCK_FUNCTIONS.put( "intSubtract", new Math.intSubtract() );
STOCK_FUNCTIONS.put( "doubleSubtract", new Math.doubleSubtract() );
STOCK_FUNCTIONS.put( "longSubtract", new Math.longSubtract() );
STOCK_FUNCTIONS.put( "divide", new Math.divide() );
STOCK_FUNCTIONS.put( "divideAndRound", new Math.divideAndRound() );
STOCK_FUNCTIONS.put( "toInteger", new Objects.toInteger() );
STOCK_FUNCTIONS.put( "toDouble", new Objects.toDouble() );
STOCK_FUNCTIONS.put( "toLong", new Objects.toLong() );
STOCK_FUNCTIONS.put( "toBoolean", new Objects.toBoolean() );
STOCK_FUNCTIONS.put( "toString", new Objects.toString() );
STOCK_FUNCTIONS.put( "size", new Objects.size() );
STOCK_FUNCTIONS.put( "toJsonString", new Objects.toJsonString() );
STOCK_FUNCTIONS.put( "squashNulls", new Objects.squashNulls() );
STOCK_FUNCTIONS.put( "recursivelySquashNulls", new Objects.recursivelySquashNulls() );
STOCK_FUNCTIONS.put( "squashDuplicates", new Objects.squashDuplicates() );
STOCK_FUNCTIONS.put( "noop", Function.noop );
STOCK_FUNCTIONS.put( "isPresent", Function.isPresent );
STOCK_FUNCTIONS.put( "notNull", Function.notNull );
STOCK_FUNCTIONS.put( "isNull", Function.isNull );
STOCK_FUNCTIONS.put( "firstElement", new Lists.firstElement() );
STOCK_FUNCTIONS.put( "lastElement", new Lists.lastElement() );
STOCK_FUNCTIONS.put( "elementAt", new Lists.elementAt() );
STOCK_FUNCTIONS.put( "toList", new Lists.toList() );
STOCK_FUNCTIONS.put( "sort", new Lists.sort() );
}
其对应函数的功能和java同名函数一样
toLower :将字符转成小写
toUpper : 将字符转成大写
concat :合并字符串
下面就不一一说明了,详情说明可以访问开源项目查看
modify-overwrite-beta相关案例讲解
字符串相关处理
input 输入:
{
"rating": {
"primary": {
"value": 3,
"value1": "ABC",
"value2": "dnf"
},
"quality": {
"value": 3
}
}
}
spec :
[
{
"operation": "modify-overwrite-beta",
"spec": {
"rating": {
"primary": {
"value": "=toString", //将 value转成字符串
"value1": "=toLower", //将value1的字符变成小写
"value2": "=toUpper", //将value2的字符变成大写
"value3": "=concat(a,b,c,d,e,c,g)", //将括号里的数值拼成字符串
"value4": "=join('_',5,4,5,6,7,8,9,90,0)", // 以‘—’将后面的元素连接在一起
"value5": "=split('_','order_item_info')", //以‘_’分割字符串
"value6": "=substring('abcdefg',3,3)", //截取‘abcdefg’的子串
"value7": "=trim", // 去除 ‘ yy ’ 前后空格
"value8": "=leftPad('abc',5,c)", // 5 - 'abc'.length()等于2,所在在左边增加两个c
"value9": "=rightPad('abc',5,d)" // 5 - 'abc'.length()等于2,所在在右边增加两个d
},
"quality": {
"value1": "=min(1,3,4,6)", // 从 1,3,4,6中选最小值赋值给value1
"value2": "=max(1,3,4,6)" // 从 1,3,4,6中选最大值赋值给value2
}
}
}
}
]
expected 输出:
{
"rating" : {
"primary" : {
"value" : "3",
"value1" : "abc",
"value2" : "DNF",
"value7" : "yy",
"value3" : "abcdecg",
"value4" : "5_4_5_6_7_8_9_90_0",
"value5" : [ "order", "item", "info" ],
"value8" : "ccabc",
"value9" : "abcdd"
},
"quality" : {
"value" : 3,
"value1" : 1,
"value2" : 6
}
}
}
数学运算
input 输入:
{
"rating": {
"primary": {
"value": 3
},
"quality": {
"value": 3
}
}
}
spec :
[
{
"operation": "modify-overwrite-beta",
"spec": {
"rating": {
"quality": {
"value1": "=min(1,3,4,6)", // 从 1,3,4,6中选最小值赋值给value1
"value2": "=max(1,3,4,6)", // 从 1,3,4,6中选最大值赋值给value2
"value3": "=abs(-100)", //取一个数据的绝对值
"value4": "=avg(1,2,3)", // 取 1,2,3 的平均值
"value5": "=intSum(1,2,3)", // int求和
"value6": "=doubleSum(1.0,2.0,3.0)", // double求和
"value7": "=longSum(10000,20000,30000)", //long求和
"value8": "=intSubtract(6,2)", //整数减法 6-2
"value9": "=doubleSubtract(6.0,2.2)", //浮点数减法6.0 - 2.2
"value10": "=divide(10,2)", //除法 10/2
"value11": "=divideAndRound(2,30,7)" //除法 30/7四舍五入,第一个2参数指的是保留几位小数
}
}
}
}
]
expected 输出:
{
"rating" : {
"primary" : {
"value" : 3
},
"quality" : {
"value" : 3,
"value1" : 1,
"value2" : 6,
"value3" : 100,
"value4" : 2.0,
"value5" : 6,
"value6" : 6.0,
"value7" : 60000,
"value8" : 4,
"value9" : 3.8,
"value10" : 5.0,
"value11" : 4.29
}
}
}
类型转换
input 输入:
{
"rating": {
"primary": {
"value1": "3",
"value2": 2,
"value3": "33",
"value4": "false",
"value5": 1999,
"value6": "123456789"
}
}
}
spec :
[
{
"operation": "modify-overwrite-beta",
"spec": {
"rating": {
"primary": {
"value1": "=toInteger", // 转换成int类型
"value2": "=toDouble", // 转换成Double类型
"value3": "=toLong", //转换成long类型
"value4": "=toBoolean", //转换成Boolean类型
"value5": "=toString", // 转换成String类型
"value6": "=size", // 求字符串长度
"value7": "=size(1,2,3,4,5,6,7,8)" //求数组元素个数
}
}
}
}
]
expected 输出:
{
"rating" : {
"primary" : {
"value1" : 3,
"value2" : 2.0,
"value3" : 33,
"value4" : false,
"value5" : "1999",
"value6" : 9,
"value7" : 8
}
}
}
数组的操作
input 输入:
{
"rating": {
"primary": {
"value0":[6,5,4,3,2,1],
"value1": [ "a", null, 1, null, "b" ],
"value2": [ "a", null, { "x": "X", "y": null, "zList" : [ "z1", null, "z3" ] }, null, "b" ],
"value3": [ "abc", "abc", "xyz", "cde", "bcd" ],
"value4": [ "abc", "abc", "xyz", "cde", "bcd" ],
"value5": [ "abc", "abc", "xyz", "cde", "bcd" ],
"value6": [ "abc", "abc", "xyz", "cde", "bcd" ]
}
}
}
spec :
[
{
"operation": "modify-overwrite-beta",
"spec": {
"rating": {
"primary": {
"value1": "=squashNulls", // 去除空值
"value2": "=recursivelySquashNulls", // 递归去除空值
"value3": "=squashDuplicates", //去除重复值
"value4": "=firstElement", //取数组第一个值
"value5": "=lastElement", // 取数组最后一个值
"value6": "=elementAt(2,@(1,value0))", // 取value0数组下标为2的值
"value7": "=toList(10)", //将元素转换数组
"value8": "=sort(@(1,value0))" //将value0升序排序
}
}
}
}
]
expected 输出:
{
"rating" : {
"primary" : {
"value0" : [ 6, 5, 4, 3, 2, 1 ],
"value1" : [ "a", 1, "b" ],
"value2" : [ "a", {"x" : "X","zList" : [ "z1", "z3" ] }, "b" ],
"value3" : [ "abc", "xyz", "cde", "bcd" ],
"value4" : "abc",
"value5" : "bcd",
"value6" : 4,
"value7" : [ 10 ],
"value8" : [ 1, 2, 3, 4, 5, 6 ]
}
}
}
不同模式结合使用的案例
不同模式结合使用的相关案例讲解
jolt的表达式是一个列表,所以我们在使用的时候可以结合多种模式一起使用
input 输入:
{
"rating": {
"primary": {
"value": 3
},
"quality": {
"value": 3
}
}
}
spec:
[
{
"operation": "shift",
"spec": {
"rating": {
"primary": {
// simple match. Put the value '4' in the output under the "Rating" field
"value": "Rating",
"max": "RatingRange"
},
// match any children of "rating"
// Shiftr has a precendence order when matching, so the "*" will match "last".
// In this case anything that isn't "primary".
"*": {
// &1 means, go up one level and grab that value and substitute it in
// in this example &1 = "quality"
"max": "SecondaryRatings.&1.Range",
"value": "SecondaryRatings.&1.Value",
//
// We want "quality" to be a value field in the output under
// "SecondaryRatings.quality.Id", but "quality" is an input key not an input value.
// The "$" operator means use the input key, instead of the input value as ouput
"$": "SecondaryRatings.&1.Id"
}
}
}
},
{
"operation": "default",
"spec": {
"Range": 5,
"SecondaryRatings": {
"*": {
// Defaut all "SecondaryRatings" to have a Range of 5
"Range": 5
}
}
}
}
]
expected 输出:
{
"Rating" : 3,
"SecondaryRatings" : {
"quality" : {
"Id" : "quality",
"Value" : 3,
"Range" : 5
}
},
"Range" : 5
}
需要查看更多详细的例子可以访问开源项目查看
github jolt教程 开源项目 jolt-universe.
gitCode jolt 教程 开源项目 jolt-universe.
gitee 码云 jot教程 开源项目 jolt-universe.