跳到主要内容

转换语言

例子

易对接通过转换语言脚本,完成原格式数据到新格式数据的转换,请看以下示例:

原数据:

{
"name": "张三",
"city": "北京"
}

转换脚本:

{
"姓名":.name,
"城市":.city
}

转换结果:

{
"姓名" : "张三",
"城市" : "北京"
}

通过以上简单的例子,简单了解脚本语言的功能,下面是详细介绍:

语言基础

转换语言主要由三部分组成:变量、控制语句、函数。

变量

先看一个示例:

转换脚本:

let postalcode="100080"
{
"姓名":.name,
"城市":.city,
"邮编": $postalcode
}

转换结果:

{
"姓名" : "张三",
"城市" : "北京",
"邮编" : "100080"
}

通过示例可以看出:

  1. 定义使用let关键字完成定义和赋值
  2. 不需要定义类型
  3. 使用"$+变量名称"引用变量
  4. 变量定义放在对象定义之外

控制语句

转换语言支持条件判断和循环语句。下面通过示例了解:

条件判断

转换脚本:

{
"姓名":.name,
"城市":.city,
"简称": if (.city=="北京") "BJ" else "XA"
}

转换结果:

{
"姓名" : "张三",
"城市" : "北京",
"简称" : "BJ"
}

通过以上示例,可以看出条件判断语句的使用方法:

  1. 使用if 发起判断,条件放在括号中
  2. 第二部分是条件为真时返回的数据(此处为BJ)
  3. else之后是条件不成立时返回的数据(此处为XA)

循环

先看一个示例:

原数据:

{
"name": "张三",
"city": "北京",
"records": [
{
"start": "2020-8",
"end": "2020-10",
"address":"海淀区"
},
{
"start": "2020-11",
"end": "2021-1",
"address":"大兴区"
},
{
"start": "2021-2",
"end": "2021-5",
"address":"朝阳区"
}
]
}

转换脚本:

{
"姓名":.name,
"城市":.city,
"出行记录":[
for
(.records)
{
"开始时间": .start,
"结束时间": .end,
"主要活动区域": .address
}
]
}

转换结果:

{
"姓名" : "张三",
"城市" : "北京",
"出行记录" : [ {
"开始时间" : "2020-8",
"结束时间" : "2020-10",
"主要活动区域" : "海淀区"
}, {
"开始时间" : "2020-11",
"结束时间" : "2021-1",
"主要活动区域" : "大兴区"
}, {
"开始时间" : "2021-2",
"结束时间" : "2021-5",
"主要活动区域" : "朝阳区"
} ]
}

通过以上示例,可以总结循环语句使用的基本规则:

  1. 通过for发起
  2. 循环访问的对方为数组,单独一行,并且放在括号中
  3. 循环产生的结果(7~11行)定义,通过“.+对象名称”的方式访问数组内容

函数

使用循环语句部分的数据示例,使用脚本:

{
"姓名":.name,
"城市":.city,
"活动地点数量":size(.records)
}

转换结果:

{
"姓名" : "张三",
"城市" : "北京",
"活动地点数量" : 3
}

size是计算数组长度函数。

函数参考

_first

查找第一个非空对象

_first([null,{"a":"b"}])

返回

{"a":"b"}

contains

判断包含关系。用于三个场合:

1.数组是否报一个元素

contains(1, [1, 2, 3])         => true

2.对象是否包含某个key值

contains("no", {"no" : false}) => true

contains(1, {"1" : false}) => true

3.字符串是否包含子字符串

contains("ab", "abc")          => true

size

返回大小。用于三个场合:

1.判断数组大小

size([1, 2, 3]) => 3

2.判断对象子元素个数

size({"1" : 3}) => 1

3.判断字符串长度

size("abcdef")  => 6

error

返回错误信息,停止转换过程。

if (not(is-array(.things)))  error("'things' is not an array"

fallback

返回第一个非null、[]、{}的值

fallback(null, [], {}, "value")

min

返回较小的值

min(10, 1)    -> 1

min("a", "b") -> "a"

min(10, null) -> null

max

返回较大值

max(10, 1)    -> 10

max("a", "b") -> "b"

max(10, null) -> null

is-number

判断是不是数值

is-number(null) => false

is-number(1) => true

is-number(1.0) => true

is-number("1") => false

is-integer

判断是不是整型

is-integer(null) => false

is-integer(1) => true

is-integer(1.0) => false

is-integer("1") => false

is-decimal

判断是不是浮点数值

is-decimal(null) => false

is-decimal(1) => false

is-decimal(1.0) => true

is-decimal("1.0") => false

number

转换为数值类型

number(23)    => 23

number("23") => 23

number("023") => 23

number(23.0) => 23.0

number(null) => null

number("ab") => error

number("",0) => 0

round

小数位四舍五入

round(1)    => 1

round(1.0) => 1

round(1.51) => 2

round(null) => null

floor

浮点数取整数部分

floor(1)    => 1

floor(1.0) => 1

floor(1.51) => 1

floor(null) => null

ceiling

浮点数向上取整

ceiling(1)    => 1

ceiling(1.0) => 1

ceiling(1.51) => 2

ceiling(null) => null

random

返回0.0~1.0之间的一个随机小数

random() => 0.24712712424

sum

对数组的值请和

sum([1,2,3])    => 6

sum([1]) => 1

sum([1.0, 2.0]) => 3.0

sum([]) => 0

sum(null) => null

_arraymax

数字元素求最大值

_arraysum([1,2,3]) =>3

_range

_range(5)=>[0,1,2,3,4]

_string-increase

_string-increase("0003",4)=>"0004"

mod

返回两个数的余数

mod(10, 2)    => 0

mod(10, 3) => 1

mod(10, 4) => 2

mod(-10, 3) => 2

mod(-10, -3) => 2

mod(10, -3) => 1

mod(null, 2) => null

mod(10, null) => null

mod(10.5, 2) => error

mod(10, 2.1) => error

mod(10, "2") => error

hash-int

返回对象的int表示

hash-int("test") => 3556808

hash-int("") => 310

hash-int({}) => 8

hash-int([]) => 1

hash-int([1,2]) => 8928

hash-int([2,1]) => 9858

hash-int([1,2]) != hash-int([2,1]) => true

hash-int(1) => 248

hash-int(null) => 6

hash-int({"a":1,"b":2}) => 10519540

hash-int({"b":2,"a":1}) => 10519540

hash-int({"a":1,"b":2}) == hash-int({"b":2,"a":1}) => true

is-string

判断是不是字符串

is-string(null)  => false

is-string("123") => true

is-string(123) => false

string

转换为字符串

string(null)  => "null"

string(123) => "123"

string("123") => "123"

test

判断是否正则匹配

test("123", "\d+")       => Error (\d not a known escape code)

test("123", "\\d+") => true

test("abc123", "\\d+") => true (matching part is enough)

test("abc123", "^\\d+$") => false

capture

//输入

{"schema" : "http://schemas.schibsted.io/thing/pulse-simple.json#1.json"}

//调用

capture(.schema, "http://(?<host>[^/]+)/(?<rest>.+)")

//结果

{

"host" : "schemas.schibsted.io",

"rest" : "thing/pulse-simple.json#1.json"

}

split

split("1,2,3,4,5", ",") => ["1", "2", "3", "4", "5"]

split("1,2,3,4,5", ";") => ["1,2,3,4,5"]

split(null, ";") => null

split(",2", ",") => ["", "2"]

split("2,", ",") => ["2"]

join

join(["a", "b", "c"], " ") => "a b c"

join(["a"], " ") => "a"

join(null, "-") => null

join([1], "-") => "1"

lowercase

lowercase("ABCÆØÅ") => "abcæøå"

lowercase(null) => null

uppercase

uppercase("abcæøå") => "ABCÆØÅ"

uppercase(null) => null

sha256-hex

sha256-hex("foo") => "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"

sha256-hex("42") => "73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049"

sha256-hex(42) => "73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049"

sha256-hex(null) => null

starts-with

starts-with("prohibition", "pro") => true

starts-with("prohibition", "pre") => false

starts-with(null, "pre") => false

ends-with

ends-with("prohibition", "pro") => false

ends-with("prohibition", "ion") => true

ends-with(null, "ion") => null

from-json

from-json("[1,2]")       => [1, 2]

from-json("[1,2", "BAD") => "BAD"

from-json("[1,2") => error

from-json(null) => null

to-json

to-json([1,2])       => "[1, 2]"

to-json(1) => "1"

to-json("foo") => "\"foo\""

to-json(null) => "null"

replace

replace("abc def ghi", " ", "-")      => "abc-def-ghi"

replace("abc def ghi", "\\s+", "-") => "abc-def-ghi"

replace(null, "\\s+", "-") => null

replace(" whoah", "^\\s+", "") => "whoah"

replace("abc def ghi", "[a-z]", "x") => "xxx xxx xxx"

replace("abc def ghi", "[a-z]+", "x") => "x x x"

trim

trim("  abc  ")    => "abc"

trim("abc") => "abc"

trim("abc \t\r\n") => "abc"

trim(false) => "false"

trim(null) => null

boolean

boolean(null)  => false

boolean("") => false

boolean(" ") => true

boolean(0) => false

boolean(1) => true

boolean(true) => true

boolean(false) => false

boolean([]) => false

boolean([1]) => true

not

not(null)  => true

not("") => true

not(" ") => false

not(0) => true

not(1) => false

not(true) => false

not(false) => true

not([]) => true

not([1]) => false

is-boolean

is-boolean(null)  => false

is-boolean(true) => true

is-boolean(false) => true

is-boolean("") => false

is-boolean(" ") => false

is-object

is-object(null)  => false

is-object({}) => true

is-object([]) => false

is-object("") => false

get-key

let lookup = {

"no" : "Norway,

"se" : "Sweden"

}



get-key($lookup, "no")

get-key($lookup, "dk", "<unknown>")

array

array(null)   => null

array([1, 2]) => [1, 2]

array("123") => error



array({"a": 1, "b": 2}) =>

[

{"key" : "a", "value" : 1},

{"key" : "b", "value" : 2}

]

is-array

is-array(null)   => false

is-array([1, 2]) => true

is-array("123") => false

flatten

flatten([[1,2], [3,4]])         => [1,2,3,4]

flatten([1, 2, 3, 4]) => [1,2,3,4]

flatten([1, [2, [3, [4, []]]]]) => [1,2,3,4]

flatten(null) => null

all

all([true, true, true])         => true

all([true, true, false]) => false

all(null) => null

all([]) => true

all("") => error

any

any([false, false, false])      => false

any([false, false, true]) => true

any(null) => null

any([]) => false

any("") => error

zip

zip(["a", "b", "c"], [1, 2, 3]) => [["a", 1], ["b", 2], ["c", 3]]

zip(["a", "b", "c"], null) => null

zip(null, [1, 2, 3]) => null

zip([], []) => []

zip([1], []) => error

zip-with-index

zip-with-index(["a", "b", "c"]) => [{"value" : "a", "index" : 0},

{"value" : "b", "index" : 1},

{"value" : "c", "index" : 2}]

zip-with-index([]) => []

zip-with-index(null) => null

zip-with-index("abc") => error

index-of

返回一个元素在数组中的位置

index-of([], 1)                 => -1

index-of([0, 1, 2], 1) => 1

index-of([0, 1, 2, null], null) => 3

index-of([0, 1, 2], null) => -1

index-of(null, 1) => null

index-of(1, 1) => error

time

返回UTC时间自1970以来的秒数

now()        -> 1.529677371698E9

round(now()) -> 1529677391

parse-time

将文本格式的日期,解析为秒计算的日期

parse-time("2018-05-30T11:46:37Z", "yyyy-MM-dd'T'HH:mm:ssX") => 1.527680797E9

parse-time("2018-05-30T11:46:37", "yyyy-MM-dd'T'HH:mm:ssX") => error

parse-time("2018-05-30T11:46:37", "yyyy-MM-dd'T'HH:mm:ssX", null) => null

parse-time(null, "yyyy-MM-dd'T'HH:mm:ssX") => null

format-time

将自1970-1-1以来以秒计算的时间值转换为特定格式的日期(时间值)。格式说明方法与java中的SimpleDateFormat相同。

format-time(1529677391, "yyyy-MM-dd'T'HH:mm:ss") => "2018-06-22T14:23:11"

format-time(0, "yyyy-MM-dd") => "1970-01-01"

format-time(null, "yyyy-MM-dd") => null

parse-url

解析URL信息

parse-url("http://example.com").scheme => "http"

parse-url("http://example.com").host => "example.com"

parse-url("http://example.com").path => null

parse-url("http://example.com/").path = "/"

parse-url("https://www.example.com/?aa=1&aa=2&bb=&cc").query => "aa=1&aa=2&bb=&cc"

parse-url("https://www.example.com/?aa=1&aa=2&bb=&cc").parameters.aa => ["1", "2"]

parse-url("https://www.example.com/?aa=1&aa=2&bb=&cc").parameters.bb => [null]

parse-url("https://www.example.com/?aa=1&aa=2&bb=&cc").parameters.cc => [null]

parse-url("ftp://username:password@host.com/").userinfo => "username:password"

parse-url("https://example.com:8443").port => 8443