这个路径是一种混合查询语言,专门用于在Mendix模型中精确定位到任意一个具体的数据点。它的核心在于区分了两种不同的模型层级:单元(Unit) 和 元素(Element),并通过特定的语法在它们之间切换。
以下是对该路径 //Projects$Module[Name='Administration']/DomainModels$DomainModel[0]@DomainModels$Entity[Name='Account']['accessRules'][0]['moduleRoles'][0] 的完整分步解析:
- 单元 (Unit): 可以理解为项目树中的“文件”或“文件夹”。例如,一个模块 (
Projects$Module)、一个模块下的领域模型 (DomainModels$DomainModel)、一个页面 (Pages$Page) 都是单元。它们是项目结构的基本组成部分。我们使用GetUnitsOfType()来查找它们。 - 元素 (Element): 可以理解为“文件”内部的具体“内容”。例如,领域模型这个“文件”内部定义的实体 (
DomainModels$Entity)、实体上的访问规则、微流中的一个“显示页面”活动,这些都是元素。我们使用GetElementsOfType()在一个单元内部查找它们。
//Projects$Module[Name='Administration']/DomainModels$DomainModel[0]
这部分的语法类似于文件系统路径或XPath,完全是在 单元(Unit) 的层级进行导航。
-
//Projects$Module[Name='Administration']//: 从项目根(root)开始进行全局搜索。Projects$Module: 搜索类型为“模块”的单元。[Name='Administration']: 过滤器,要求这个模块单元的Name属性必须是 "Administration"。- 对应API:
root.GetUnitsOfType('Projects$Module')然后筛选出Name匹配的那个。
-
/DomainModels$DomainModel[0]/: 从上一步找到的 "Administration" 模块单元开始,向下查找其直接子单元。DomainModels$DomainModel: 查找类型为“领域模型”的子单元。[0]: 索引器,因为一个模块只有一个领域模型,所以取第一个(也是唯一一个)。- 对应API:
admin_module.GetUnitsOfType('DomainModels$DomainModel')[0]
到此为止,我们已经成功定位到了 Administration 模块的领域模型这个单元**。
@DomainModels$Entity[Name='Account']
这是整个路径中最关键的转折点。
@符号: 这是一个切换符。它标志着我们的查询从“单元层级”进入到“元素层级”。也就是说,我们不再查找“文件”,而是开始查找刚才找到的那个领域模型“文件”的内部内容。DomainModels$Entity[Name='Account']: 在当前单元(领域模型)内部,查找类型为“实体”(Entity)的元素,并且该元素的Name属性为 "Account"。- 对应API:
domain_model.GetElementsOfType('DomainModels$Entity')然后筛选出Name匹配的那个。
到此为止,我们已经成功从领域模型单元中,找到了名为 Account 的这个元素**。
['accessRules'][0]['moduleRoles'][0]
这部分用于访问 Account 元素的内部属性。这里的语法看起来像字典或列表的访问,但其背后的 API 调用机制是特定的,这也是您指正的关键点。
对于一个元素对象,访问其复杂属性(尤其是列表类型的属性)必须通过 .GetProperty('key').Value 的模式。
-
['accessRules']- 含义: 获取
Account元素的accessRules属性。 - 对应API:
account_entity.GetProperty('accessRules')。这个调用会返回一个Property对象,真正的属性值(一个访问规则列表)存储在该对象的.Value属性中。所以完整访问是account_entity.GetProperty('accessRules').Value。
- 含义: 获取
-
[0]- 含义: 对上一步返回的访问规则列表进行取值,获取列表中的第一个元素。
- 对应API: 对
.Value返回的列表进行标准的索引操作,即... .Value[0]。
-
['moduleRoles']和[0]- 含义: 重复以上模式。在上一步获取到的“访问规则”元素上,继续获取其
moduleRoles属性,并取出列表中的第一个值。 - 对应API:
first_access_rule.GetProperty('moduleRoles').Value[0]。
- 含义: 重复以上模式。在上一步获取到的“访问规则”元素上,继续获取其
完整的理解是:
- 路径前半段 (
//和/) 是在项目结构“文件系统”(单元树)中进行导航,使用GetUnitsOfType()实现。 @符号是分界线,标志着从导航“文件”(单元)转为查询“文件内容”(元素),开始使用GetElementsOfType()。- 路径后半段 (
['...'][0]) 是在元素内部访问其属性,其核心 API 模式是.GetProperty('属性名').Value,然后再进行后续的列表索引等操作。
好的。基于我们之前确定的正确原理(区分单元/元素,以及使用.GetProperty('key').Value模式),我现在对您提供的所有查询描述进行一次完整的、系统性的理解和翻译。
这表明您提供的查询描述是一套非常精准和一致的规则,现在我可以将其完全映射到实际的API调用上。
您提供的每一条注释都遵循着一个统一的逻辑,即:
- 单元路径: 首先通过
//和/定位到一个具体的 单元(Unit)。 - 查询/访问符: 接着使用
@符号,这个符号有两种含义,这也是一个关键点:- 含义A - 访问单元属性: 如果
@后面直接跟['属性名'],代表我们要访问这个单元本身的某个复杂属性。 - 含义B - 查询单元内元素: 如果
@后面跟类型名$元素名,代表我们要在这个单元内部查询所有属于该类型的元素(Element)。
- 含义A - 访问单元属性: 如果
- 属性/元素遍历: 最后通过
['key'][index]的形式,使用.GetProperty('key').Value和列表索引[index]的组合,在复杂的属性或元素结构中进行深入钻取,直到找到目标数据。
下面,我将逐一解析您给出的每个例子,来证明我的理解。
- 单元定位: 首先通过
root.GetUnitsOfType('Navigation$NavigationDocument')[0]找到唯一的导航配置单元,我们称之为nav_doc_unit。 - 查询解析:
@['profiles'][0]['name']- 含义: 访问
nav_doc_unit单元的profiles属性,取第一个 Profile,再获取它的name属性。 - 对应API:
profiles_list = nav_doc_unit.GetProperty('profiles').Value first_profile = profiles_list[0] profile_name = first_profile.GetProperty('name').Value
- 含义: 访问
@['profiles'][0]['homePage']['page']- 含义: 在第一个 Profile 中,获取
homePage对象,再从中获取page的值。 - 对应API:
# ... 获取 first_profile homepage_obj = first_profile.GetProperty('homePage').Value page_name = homepage_obj.GetProperty('page').Value
- 含义: 在第一个 Profile 中,获取
@['profiles'][0]['menuItemCollection']['items']- 含义: 获取菜单项集合,这是一个包含了所有一级菜单项的列表。后续的
['action']['pageSettings']['page']等访问,都是在这个列表的每个元素上,递归地使用.GetProperty().Value模式进行深入访问。 - 对应API:
# ... 获取 first_profile menu_collection = first_profile.GetProperty('menuItemCollection').Value menu_items_list = menu_collection.GetProperty('items').Value # 之后可以遍历 menu_items_list
- 含义: 获取菜单项集合,这是一个包含了所有一级菜单项的列表。后续的
- 单元定位: 通过
root.GetUnitsOfType('Security$ProjectSecurity')[0]找到项目级安全配置单元,称之为proj_sec_unit。 - 查询解析:
@['demoUsers']- 含义: 访问
proj_sec_unit单元的demoUsers属性,得到一个演示用户对象的列表。 - 对应API:
demo_users_list = proj_sec_unit.GetProperty('demoUsers').Value
- 含义: 访问
@['userRoles']- 含义: 访问
proj_sec_unit单元的userRoles属性,得到一个用户角色对象的列表。 - 对应API:
user_roles_list = proj_sec_unit.GetProperty('userRoles').Value
- 含义: 访问
- 对于单个用户角色
['moduleRoles']- 含义: 在单个用户角色对象上,获取其
moduleRoles属性。 - 对应API:
module_roles_list = user_role_obj.GetProperty('moduleRoles').Value
- 含义: 在单个用户角色对象上,获取其
- 单元定位: 通过路径找到特定模块下的安全配置单元,称之为
mod_sec_unit。 - 查询解析:
@['moduleRoles']- 含义: 访问
mod_sec_unit单元的moduleRoles属性,得到一个模块角色对象的列表。 - 对应API:
module_roles_list = mod_sec_unit.GetProperty('moduleRoles').Value
- 含义: 访问
- 单元定位: 通过路径找到
ActiveSessions这个页面单元,称之为page_unit。 - 查询解析 (这里包含了两种
@的用法):@['allowedRoles']- 含义 (用法A): 访问
page_unit单元本身的allowedRoles属性,得到一个允许访问的模块角色名称列表。 - 对应API:
allowed_roles_list = page_unit.GetProperty('allowedRoles').Value
- 含义 (用法A): 访问
@Pages$MicroflowClientAction- 含义 (用法B): 在
page_unit单元内部,查询所有类型为Pages$MicroflowClientAction的元素。这会返回一个列表,包含了页面上所有调用微流的按钮或事件。 - 对应API:
microflow_actions_list = page_unit.GetElementsOfType('Pages$MicroflowClientAction') - 之后,对于列表中的每个
action元素,再通过action.GetProperty('microflowSettings').Value等方式深入访问。
- 含义 (用法B): 在
- 单元定位: 通过路径找到
NewAccount这个微流单元,称之为mf_unit。 - 查询解析 (同样包含两种
@的用法):@['allowedModuleRoles']- 含义 (用法A): 访问
mf_unit单元本身的allowedModuleRoles属性,得到允许执行此微流的模块角色列表。 - 对应API:
allowed_roles_list = mf_unit.GetProperty('allowedModuleRoles').Value
- 含义 (用法A): 访问
@Microflows$ShowPageAction- 含义 (用法B): 在
mf_unit单元内部,查询所有类型为Microflows$ShowPageAction的元素(即所有“显示页面”活动)。 - 对应API:
show_page_actions_list = mf_unit.GetElementsOfType('Microflows$ShowPageAction')
- 含义 (用法B): 在
@Microflows$MicroflowCall- 含义 (用法B): 在
mf_unit单元内部,查询所有类型为Microflows$MicroflowCall的元素(即所有“调用微流”活动)。 - 对应API:
microflow_calls_list = mf_unit.GetElementsOfType('Microflows$MicroflowCall')
- 含义 (用法B): 在