- DataPath可称为数据路径。
- DataPath是在Dorado的客户端所使用的,用于描述如何提取、挖掘数据的表达式。其作用比较类似于XML中所使用的XPath。
- DataPath既可以作用在普通的JSON数据上,也可以作用在Dorado所特有的EntityList+Entity数据上。
假设我们现在有一组如下结构的Entit+EntityList数据,其中包含Department和Employee两种实体类型,其中Department支持递归嵌套。下面的说明和示例都将围绕这组数据展开。
[ { id: "D1", name: "XX部1", departments: [ { id: "D11", name: "XX部2", employees: [ { id: "0001", name: "John", sex: "male", salary: 5000 }, ... ] }, ... ] }, ... ]
DataPath的基本语法为:
属性名1(参数1,参数2,..)[逻辑表达式1,逻辑表达式2,..].属性名2(参数1,参数,..2)[逻辑表达式1,逻辑表达式2,..].属性名n..
DataPath中各种特殊符号的说明:
- ; - 用于分隔多个表达式的分隔符。例如:<code>表达式1;表达式2</code>,最终得到的结果是这两个表达式的结果的简单合集(即可能包含重复元素的合计)。
- . - 用于分隔不同层级间对象的属性。例如:<code>employee.id</code>表示employee子对象的id属性。
- * - 用于表示某一层级中所有的对象,一般仅用于表示顶层集合中的对象,且可以省略。例如:<code>*.id</code>表示所有顶层对象的id属性。
- () - 用于定义一组表达式执行参数,多个参数之间以","分割。目前支持的参数包括:
- repeat - 重复的执行当前的表达式片段直到无法找到更多的子对象为止。可简写为"R"。例如:
.employees(repeat)
- 或
.employees(R)
- 表示所有employees属性中的对象的集合,这些对象会被提取出来被平行的放置到一个返回的数组中。
- leaf - 重复的执行当前的表达式片段找出所有的叶子对象。可简写为"L"。
- 数字 - 表示仅返回找到的前n个对象。
- @ - 用于逻辑表达式中,表示当前正被过滤的数据对象。
- [] - 用于定义一组逻辑表达式以对数据进行过滤,其中如果要定义多个逻辑表达式可以以","进行区隔。例如:
employees[@.get("sex")=="male"]
- 表示筛选出性别为男性的员工。
- # - DataPath中支持一些以#开头的特殊的逻辑表达式,用于声明对Entity对象的过滤方式。具有如下几种取值:
- #current - 表示集合中的当前Entity对象。例如:
employees[#current]
- 表示返回employees集合中的当前Employee对象。
- #dirty - 表示集合中所有在客户端被改变过的(包含被删除的)Entity对象。
- #new - 表示集合中所有在客户端新增的Entity对象。
- #modified - 表示集合中所有在客户端被修改过的Entity对象。
- #deleted - 表示集合中所有在客户端被标记为已删除的Entity对象。
- # - #current的简式。例如:
#employees
- 与
employees[#current]
- 具有完全相同的语义。
- ! - 表示后面是一段自定义的数据路径片段。例如:
!CURRENT_NODE.children
- 中的CURRENT_NODE就是一个自定义片段。见jsdoc中关于dorado.DataPath.registerInterceptor()方法的说明。
更多的示例:
- null(即空) - 相当于直接返回被查询的数据。表示顶层集合中所有的(不包含被删除的)Department。
- * - 同上。
- # - 表示顶层集合中的当前Department。
- [#current] - 同上。
- [#dirty] - 表示顶层集合中所有在客户端被改变过的(包含被删除的)Department。
- #.employees - 表示顶层集合中当前Department中所有的Employee。
- #.#employees - 表示顶层集合中当前Department中的当前Employee。
- #.#departments.#employees - 表示顶层集合中当前Department中的当前Employee。
- *.departments - 表示所有第二层的Department。
- .departments - 同上。
- departments(repeat) - 表示所有Department的集合。注意:示例数据的顶层是一个集合,而在正常情况下是不能利用表达式来获取集合属性的。除非当一个具有repeat或leaf特性的表达式片段被应用于顶层集合时。引擎允许这样的特例,在此种情况下引擎会暂时忽略表达式片段中的属性名。
- .departments(R) - 表示除顶层Department外所有其它Department的集合。
- .#departments(R) - 表示除顶层Department外所有其它各层中当前Department的集合。
- #departments(R) - 表示各层当前Department的集合。
- #departments(leaf) - 表示最末端的当前Department。即通过不断的尝试获取当前Department中的当前Department,直到最末端那个Department。
- #departments(L) - 同上。
- #departments(L).#employees - 表示最末端的当前Department中的当前Employee。此表达式返回的结果是所有匹配Employee组成的数组。
- .employees(R) - 表示所有employees属性中的对象的集合,即所有的Employee对象。
- .#employees(R) - 表示所有Department中的当前Employee,将以数组的形式返回这些Employee实体的集合。
- .employees(R)[@.get("sex")=="male"] - 表示所有Department中的男性Employee,将以数组的形式返回这些Employee实体的集合。
- .employees(R)[#dirty,@.get("sex")=="male"] - 表示所有Department中的状态为已修改的男性Employee,将以数组的形式返回这些Employee实体的集合。
- .employees(R)[@.get("salary")>3500 && @.get("sex")=="male"] - 同上。
- .employees(R)[@.get("salary")>3500, @.get("sex")=="male"] - 表示所有Department中的薪水高于3500的男性Employee,将以数组的形式返回这些Employee实体的集合。
- .employees(R).id - 表示返回所有Employee对象的id属性值的集合,即所有的Employee对象的id。