About | Tutorial | Rule Engine | GRL | GRL JSON | RETE Algorithm | Functions | FAQ | Benchmark
从1.8.0版本开始,Grule支持使用JSON数据作为事实。能够使用户使用JSON格式表述他们的事实,并且能够像正常代码一样把这些事实加载到DataContext
中。加载的JSON事实在Grule脚本现在是可见的了。
假设我们的JSON格式如下
{
"name" : "John Doe",
"age" : 24,
"gender" : "M",
"height" : 74.8,
"married" : false,
"address" : {
"street" : "9886 2nd St.",
"city" : "Carpentersville",
"state" : "Illinois",
"postal" : 60110
},
"friends" : [ "Roth", "Jane", "Jake" ]
}
你可以把JSON存在字节数组中
myJSON := []byte (...your JSON here...)
然后简单地添加JSON变量到 DataContext
// create new instance of DataContext
dataContext := ast.NewDataContext()
// add your JSON Fact into data context using AddJSON() function.
err := dataContext.AddJSON("MyJSON", myJSON)
是的,你可以添加很多事实到上下文中,而且你可以混合JSON事实(使用AddJSON)和正常的Go事实(使用Add)。
在GRL较本周,当你添加到 DataContext
,通过你提供的标签,事实是可见的。比如下面的代码是添加你的JSON,而且被打上MyJSON
标签。
err := dataContext.AddJSON("MyJSON", myJSON)
是的,你可以使用任何一个标签,只要他是一个词。
正如使用开头展示的JSON,你的GRL when
范围可以如下评估你的json。
when
MyJSON.name == "John Doe"
或者
when
MyJSON.address.city.StrContains("ville")
或者
when
MyJSON.age > 30 && MyJSON.height < 60
你可以像使用Map
一样访问JSON对象,也可以像正常对象一样,也可以两者混用
when
MyJSON["name"] == "John Doe"
或者
when
MyJSON["address"].city.StrContains("ville")
或者
when
MyJSON.age > 30 && MyJSON["HEIGHT".ToLower()] < 60
你可以像正常的数组一样访问JSON 数组元素。
when
MyJSON.friends[3] == "Jake"
是的,你可以在then
范围内写入你的值到JSON事实。这些变动的值将会在接下来的循环中被访问到。但是,有一些警告(参考下面的 你应该知道的)。
正如开头展示的JSON,你的GRL then
范围可以像如下修改你的试事实。
then
MyJSON.name = "Robert Woo";
或者
then
MyJSON.address.city = "Corruscant";
或者
then
MyJSON.age = 30;
这个是完美的直接方式。但是有一些别扭。
-
你可以修改不仅仅是你JSON对象的成员变量,你可以修改类型。假设你的规则在接下来的评估过程中可以处理新的类型,否则强烈建议不要这么做。
例子:
你可以改变
MyJSON.age
到 字符串.then MyJSON.age = "Thirty";
这个修改在遇到下面的规则时,会导致引擎panic。
when myJSON.age > 25
-
你可以赋值给一个不存在的成员变量。
比如:
then MyJSON.category = "FAT";
其中
category
变量在原始JSON中不存在。
正如开始所展示的JSON,在你的then
范围内,你可以如下修改你的json事实。
then
MyJSON["name"] = "Robert Woo";
或者
then
MyJSON["address"]["city"] = "Corruscant";
或者
then
MyJSON["age"] = 30;
正如对象格式的,同样适用。
-
你可以修改不仅仅是你JSON对象的成员变量,你可以修改类型。假设你的规则在接下来的评估过程中可以处理新的类型,否则强烈建议不要这么做。
举例
你可以修改
MyJSON.age
到 字符串.then MyJSON["age"] = "Thirty";
这个修改在遇到下面的规则时,会导致引擎panic。
when myJSON.age > 25
-
你可以赋值给一个不存在的成员变量。
举例:
then MyJSON["category"] = "FAT";
其中
category
变量在原始JSON中不存在。
你可以使用索引修改一个数组元素。
then
MyJSON.friends[3] == "Jake";
指定的索引必须有效。如果越界,Grule将会panic。正如正常的JSON,你可以使用其他类型去替换任意元素。你也可以获取数组的长度。
when
MyJSON.friends.Length() > 4;
你可以通过 Append
函数往数组里面添加元素. Append 也可以添加一个不同类型的元素到数组中。 (同样的警示 适用于 w.r.t. 修改指定类型)
then
MyJSON.friends.Append("Rubby", "Anderson", "Smith", 12.3);
已知问题
没有内置函数可以很容易地帮助使用者检查数组内容,比如Contains(value) bool。
- 在你添加一个JSON事实到
DataContext
, JSON串的修改将不会影响在DataContext
中的事实。反方向同样适用, 在DataContext
中的修改将不会改变JSON串。 - 你可以在
then
范围内修改你的JSON事实,但是不像正常的Go事实,这些修改将不会影响你的原始JSON字符串。如果你想实现这样的功能,你可以提前解析JSON到一个struct
,然后可以像正常一样添加你的struct
到DataContext
。