Skip to content

Instantly share code, notes, and snippets.

@engalar
Last active September 3, 2025 08:42
Show Gist options
  • Select an option

  • Save engalar/58c4ec7e7ee15e48db3117a155eccf6c to your computer and use it in GitHub Desktop.

Select an option

Save engalar/58c4ec7e7ee15e48db3117a155eccf6c to your computer and use it in GitHub Desktop.
untype路径语法

这个路径是一种混合查询语言,专门用于在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() 在一个单元内部查找它们。

路径分步详解

第一 & 第二部分:单元(Unit)的导航

//Projects$Module[Name='Administration']/DomainModels$DomainModel[0]

这部分的语法类似于文件系统路径或XPath,完全是在 单元(Unit) 的层级进行导航。

  1. //Projects$Module[Name='Administration']

    • //: 从项目根(root)开始进行全局搜索。
    • Projects$Module: 搜索类型为“模块”的单元。
    • [Name='Administration']: 过滤器,要求这个模块单元的 Name 属性必须是 "Administration"。
    • 对应API: root.GetUnitsOfType('Projects$Module') 然后筛选出 Name 匹配的那个。
  2. /DomainModels$DomainModel[0]

    • /: 从上一步找到的 "Administration" 模块单元开始,向下查找其直接子单元。
    • DomainModels$DomainModel: 查找类型为“领域模型”的子单元。
    • [0]: 索引器,因为一个模块只有一个领域模型,所以取第一个(也是唯一一个)。
    • 对应API: admin_module.GetUnitsOfType('DomainModels$DomainModel')[0]

到此为止,我们已经成功定位到了 Administration 模块的领域模型这个单元**。


第三部分:从单元(Unit)切换到元素(Element)

@DomainModels$Entity[Name='Account']

这是整个路径中最关键的转折点。

  • @ 符号: 这是一个切换符。它标志着我们的查询从“单元层级”进入到“元素层级”。也就是说,我们不再查找“文件”,而是开始查找刚才找到的那个领域模型“文件”的内部内容
  • DomainModels$Entity[Name='Account']: 在当前单元(领域模型)内部,查找类型为“实体”(Entity)的元素,并且该元素的 Name 属性为 "Account"。
  • 对应API: domain_model.GetElementsOfType('DomainModels$Entity') 然后筛选出 Name 匹配的那个。

到此为止,我们已经成功从领域模型单元中,找到了名为 Account 的这个元素**。


第四部分:元素(Element)属性的访问

['accessRules'][0]['moduleRoles'][0]

这部分用于访问 Account 元素的内部属性。这里的语法看起来像字典或列表的访问,但其背后的 API 调用机制是特定的,这也是您指正的关键点。

对于一个元素对象,访问其复杂属性(尤其是列表类型的属性)必须通过 .GetProperty('key').Value 的模式。

  1. ['accessRules']

    • 含义: 获取 Account 元素的 accessRules 属性。
    • 对应API: account_entity.GetProperty('accessRules')。这个调用会返回一个 Property 对象,真正的属性值(一个访问规则列表)存储在该对象的 .Value 属性中。所以完整访问是 account_entity.GetProperty('accessRules').Value
  2. [0]

    • 含义: 对上一步返回的访问规则列表进行取值,获取列表中的第一个元素。
    • 对应API:.Value 返回的列表进行标准的索引操作,即 ... .Value[0]
  3. ['moduleRoles'][0]

    • 含义: 重复以上模式。在上一步获取到的“访问规则”元素上,继续获取其 moduleRoles 属性,并取出列表中的第一个值。
    • 对应API: first_access_rule.GetProperty('moduleRoles').Value[0]

总结

完整的理解是:

  1. 路径前半段 (///) 是在项目结构“文件系统”(单元树)中进行导航,使用 GetUnitsOfType() 实现。
  2. @ 符号是分界线,标志着从导航“文件”(单元)转为查询“文件内容”(元素),开始使用 GetElementsOfType()
  3. 路径后半段 (['...'][0]) 是在元素内部访问其属性,其核心 API 模式是 .GetProperty('属性名').Value,然后再进行后续的列表索引等操作。

好的。基于我们之前确定的正确原理(区分单元/元素,以及使用.GetProperty('key').Value模式),我现在对您提供的所有查询描述进行一次完整的、系统性的理解和翻译。

这表明您提供的查询描述是一套非常精准和一致的规则,现在我可以将其完全映射到实际的API调用上。


我的完整理解

您提供的每一条注释都遵循着一个统一的逻辑,即:

  1. 单元路径: 首先通过 /// 定位到一个具体的 单元(Unit)
  2. 查询/访问符: 接着使用 @ 符号,这个符号有两种含义,这也是一个关键点:
    • 含义A - 访问单元属性: 如果 @ 后面直接跟 ['属性名'],代表我们要访问这个单元本身的某个复杂属性。
    • 含义B - 查询单元内元素: 如果 @ 后面跟 类型名$元素名,代表我们要在这个单元内部查询所有属于该类型的元素(Element)
  3. 属性/元素遍历: 最后通过 ['key'][index] 的形式,使用 .GetProperty('key').Value 和列表索引 [index] 的组合,在复杂的属性或元素结构中进行深入钻取,直到找到目标数据。

下面,我将逐一解析您给出的每个例子,来证明我的理解。


1. 导航配置 (//Navigation$NavigationDocument[0])

  • 单元定位: 首先通过 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
    • @['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

2. 项目级安全配置 (//Security$ProjectSecurity[0])

  • 单元定位: 通过 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

3. 模块级安全配置 (.../Security$ModuleSecurity[0])

  • 单元定位: 通过路径找到特定模块下的安全配置单元,称之为 mod_sec_unit
  • 查询解析:
    • @['moduleRoles']
      • 含义: 访问 mod_sec_unit 单元的 moduleRoles 属性,得到一个模块角色对象的列表。
      • 对应API: module_roles_list = mod_sec_unit.GetProperty('moduleRoles').Value

4. 页面配置 (.../Pages$Page[Name='ActiveSessions'])

  • 单元定位: 通过路径找到 ActiveSessions 这个页面单元,称之为 page_unit
  • 查询解析 (这里包含了两种 @ 的用法):
    • @['allowedRoles']
      • 含义 (用法A): 访问 page_unit 单元本身的 allowedRoles 属性,得到一个允许访问的模块角色名称列表。
      • 对应API: allowed_roles_list = page_unit.GetProperty('allowedRoles').Value
    • @Pages$MicroflowClientAction
      • 含义 (用法B):page_unit 单元内部查询所有类型为 Pages$MicroflowClientAction元素。这会返回一个列表,包含了页面上所有调用微流的按钮或事件。
      • 对应API: microflow_actions_list = page_unit.GetElementsOfType('Pages$MicroflowClientAction')
      • 之后,对于列表中的每个 action 元素,再通过 action.GetProperty('microflowSettings').Value 等方式深入访问。

5. 微流配置 (.../Microflows$Microflow[Name='NewAccount'])

  • 单元定位: 通过路径找到 NewAccount 这个微流单元,称之为 mf_unit
  • 查询解析 (同样包含两种 @ 的用法):
    • @['allowedModuleRoles']
      • 含义 (用法A): 访问 mf_unit 单元本身的 allowedModuleRoles 属性,得到允许执行此微流的模块角色列表。
      • 对应API: allowed_roles_list = mf_unit.GetProperty('allowedModuleRoles').Value
    • @Microflows$ShowPageAction
      • 含义 (用法B):mf_unit 单元内部查询所有类型为 Microflows$ShowPageAction元素(即所有“显示页面”活动)。
      • 对应API: show_page_actions_list = mf_unit.GetElementsOfType('Microflows$ShowPageAction')
    • @Microflows$MicroflowCall
      • 含义 (用法B):mf_unit 单元内部查询所有类型为 Microflows$MicroflowCall元素(即所有“调用微流”活动)。
      • 对应API: microflow_calls_list = mf_unit.GetElementsOfType('Microflows$MicroflowCall')

Mendix模型查询路径解析指南

本文档旨在详细阐述用于解析Mendix应用模型的特定查询路径语法,以便于插件开发中精确地提取所需配置信息。

1. 导航配置 (Navigation)

导航配置定义了用户如何在应用中进行跳转,包括菜单结构和各类首页。

  • 目标单元: //Navigation$NavigationDocument[0]

    • 此路径定位到项目中唯一的导航配置单元。
  • 核心属性解析 (@['...']):

    • @['profiles'][0]: 访问第一个导航配置文件(Profile),通常是 Responsive。所有后续路径都基于此 Profile。

    • 首页配置:

      • ...['homePage']['page']: 获取默认首页的 页面 限定名称 (例如, MyFirstModule.Page)。
      • ...['homePage']['microflow']: 获取默认首页的 微流 限定名称。
        • 注:pagemicroflow 属性互斥,只有一个会存在。
      • ...['roleBasedHomePages']: 获取一个基于用户角色的首页配置列表。
        • 对于列表中的每个配置:
          • ...[0]['userRole']: 获取指定的 用户角色 名称。
          • ...[0]['page']...[0]['microflow']: 获取该角色对应的首页页面或微流。
      • ...['notFoundHomepage']: 获取当页面未找到时的回退页面配置 (['page']['microflow'])。
    • 菜单项配置:

      • ...['menuItemCollection']['items']: 获取一个包含所有顶级菜单项的列表。
        • 对于列表中的每个菜单项,其定义是互斥的:它要么包含一个动作 (action),要么包含一组子菜单 (items),但不能同时存在。
        • 当菜单项包含动作时:
          • 如果动作为 Pages$PageClientAction 类型,则通过 ['action']['pageSettings']['page'] 获取其链接的 页面 限定名称。
          • 如果动作为 Pages$MicroflowClientAction 类型,则通过 ['action']['microflowSettings']['microflow'] 获取其链接的 微流 限定名称。

2. 应用级别安全配置 (Security)

此配置定义了整个应用的用户角色、演示用户等全局安全设置。

  • 目标单元: //Security$ProjectSecurity[0]

    • 此路径定位到项目中唯一的应用级别安全配置单元。
  • 核心属性解析 (@['...']):

    • @['userRoles']: 获取一个包含所有 用户角色 配置的列表。
      • 对于每个用户角色对象,可通过 ['name'] 访问其名称,通过 ['moduleRoles'] 访问一个与之关联的 模块角色 限定名数组 (例如, ['Administration.Administrator', 'System.Administrator'])。
    • @['demoUsers']: 获取一个包含所有 演示用户 配置的列表。
      • 对于每个演示用户对象,可通过 ['userName']['password'] 访问其用户名和密码,并通过 ['userRoles'] 访问其被分配的 用户角色 列表。

3. 模块级别安全配置 (Module Security)

此配置定义了单个模块内部的角色及其权限。

  • 目标单元: //Projects$Module[Name='...']/Security$ModuleSecurity[0]

    • 此路径定位到指定模块内部的安全配置单元。
  • 核心属性解析 (@['...']):

    • @['moduleRoles']: 获取一个包含该模块内所有 模块角色 定义的列表。
      • 对于每个模块角色对象,可通过 ['name'] 访问其名称。

4. 页面配置 (Page)

页面单元不仅定义了其自身的访问权限,还包含了页面内部的所有动作和事件。

  • 目标单元: //.../Pages$Page[Name='...']

    • 此路径定位到项目中的一个具体页面单元 (例如, Administration.ActiveSessions)。
  • 权限配置:

    • @['allowedRoles']: 获取一个 模块角色限定名 的数组,定义了哪些模块角色可以直接访问此页面 (例如, ['Administration.Administrator'])。
  • 页面内的动作调用 (元素查询):

    • @Pages$PageClientAction: 查询页面内所有指向其他 页面 的调用(如按钮、事件等)。
      • 对于返回的每个动作元素,可通过 ['pageSettings']['page'] 获取目标页面的限定名称。
    • @Pages$MicroflowClientAction: 查询页面内所有调用 微流 的动作。
      • 对于返回的每个动作元素,可通过 ['microflowSettings']['microflow'] 获取目标微流的限定名称。

5. 微流配置 (Microflow)

微流单元定义了自身的执行权限以及内部包含的业务逻辑活动。

  • 目标单元: //.../Microflows$Microflow[Name='...']

    • 此路径定位到项目中的一个具体微流单元 (例如, Administration.NewAccount)。
  • 权限配置:

    • @['allowedModuleRoles']: 获取一个 模块角色限定名 的数组,定义了哪些模块角色可以执行此微流。
  • 微流内的活动 (元素查询):

    • @Microflows$ShowPageAction: 查询微流内所有的“显示页面”活动。
      • 对于返回的每个活动元素,可通过 ['pageSettings']['page'] 获取其要显示的页面限定名称。
    • @Microflows$MicroflowCall: 查询微流内所有的“调用微流”活动。
      • 对于返回的每个活动元素,可通过 ['microflow'] 获取其要调用的微流限定名称。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment