手把手教你通过JSON Schema判断BpmnJS元素属性结构~

简介: 手把手教你通过JSON Schema判断BpmnJS元素属性结构~

前言


在上一篇文章 手把手教你玩转BpmnJS元素属性更新 一文中,跟大家讲解了 如何通过已有的JSON schema 定义与完整 XML 来解析属性结构通过两个官方 API 更新属性的方式及注意事项


那么假设现在只有一个 JSON Schema 文件,怎么判断属性的构成呢?文本就带大家分析 如何从JSON Schema 判断属性结构


1. 分析 JSON Schema


该文件的每个字段的具体定义和编写方式,具体请查看 BpmnJS自定义描述文件说明。但是因为平时了解到大家对自定义这一块一般需求比较少,所以这里就用 camunda 团队新出的zeebe引擎来举例吧,这也是讨论群里一个小伙伴问我的问题。


完整的 JSON 文件请查看bpmn-process-designer/packages/moddle-extensions/zeebe.json,这里节选了ioMapping 输入输出配置


{
types: [
    {
      "name": "ZeebeServiceTask",
      "extends": [
        "bpmn:ServiceTask",
        "bpmn:BusinessRuleTask",
        "bpmn:ScriptTask",
        "bpmn:SendTask",
        "bpmn:EndEvent",
        "bpmn:IntermediateThrowEvent"
      ],
      "properties": [
        {
          "name": "retryCounter",
          "type": "String",
          "isAttr": true
        }
      ]
    },
    {
      "name": "IoMapping",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "ioMapping",
          "type": "IoMapping"
        },
        {
          "name": "inputParameters",
          "isMany": true,
          "type": "Input"
        },
        {
          "name": "outputParameters",
          "isMany": true,
          "type": "Output"
        }
      ],
      "meta": {
        "allowedIn": [
          "bpmn:CallActivity",
          "bpmn:Event",
          "bpmn:ReceiveTask",
          "zeebe:ZeebeServiceTask",
          "bpmn:SubProcess"
        ]
      }
    },
    {
      "name": "InputOutputParameter",
      "properties": [
        {
          "name": "source",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "target",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Input",
      "superClass": [
        "InputOutputParameter"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:CallActivity",
          "zeebe:ZeebeServiceTask",
          "bpmn:SubProcess"
        ]
      }
    },
    {
      "name": "Output",
      "superClass": [
        "InputOutputParameter"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:CallActivity",
          "bpmn:Event",
          "bpmn:ReceiveTask",
          "zeebe:ZeebeServiceTask",
          "bpmn:SubProcess"
        ]
      }
    }
]
}


🚀 这里也算是一点小技巧:只要是 types 数组中的某一个定义的properties 属性配置中如果这个属性的 type 不是 Number、Boolean、String 这几个基础类型,而是 JSON Schema 中定义的类型的话,通常这个属性都是绑定一个 通过 moddle.create 创建的对应类型的实例


1.1 分析 IoMapping


首先查看这个类型的 supperClass 或者 extends 字段,这里定义的是supperClass:[Element],说明这个属性基本上在 XML 文件中都体现为一个标签,并且标签名为zeebe:ioMapping


然后就是 meta 字段,一般这个字段里面会有一个 allowedIn 的数组格式的字段,表示 该属性或者标签(IoMapping)允许被配置/插入哪些类型的元素/标签中,通过 通配符 * 表示允许插入所有标签/属性中。此时根据配置 IoMapping 标签可以被插入到  SubProcess 子流程、CallActivity 调用任务、zeebe:ZeebeServiceTask Zeebe服务任务中


zeebe:ZeebeServiceTask的定义中,则是用extend扩展原来的ServiceTas等类型元素的,所以IoMapping 定义里 allowedIn 中的 ZeebeServiceTask 其实就可以理解为 ServiceTask 等元素的替代指示


最后分析 properties 配置,可以看到IoMapping 接收三个属性配置


  • ioMapping:类型就是IoMapping,表示这个标签内部还可以插入 IoMapping 标签,即支持嵌套


  • inputParameters:类型为Input,且isMany 为 true,表示这里是一个 数组形式,在 js 中体现为**inputParameters: []**


  • outputParameters:类型为Output,其他的信息与inputParameters一致


总结:


IoMapping 在 xml 中体现为一个标签形式,内部可以继续插入 IoMapping 标签;并且接收其他两个属性 inputParameters 和 outputParameters。


并且 inputParameters 与 outputParameters 都不是简单的数据类型,而且是数组格式,所以给这两个属性设置属性值时,内部的属性也需要通过 moddle.create 创建实例。


在我们创建一个 IoMapping 实例时,步骤和结果如下:


const moddle = modeler.get('moddle')
const ioMapping = moddle.create('zeebe:IoMapping', {inputParameters: [], outputParameters: []})
// 结果如下:
IoMapping = {
    $type: 'zeebe:IoMapping',
    inputParameters: [],
    outputParameters: []
}


1.2 ZeebeServiceTask 没有 IoMapping


虽然分析了 IoMapping 之后,知道了这个属性在配置时该怎么操作;但是,在zeebe:ZeebeServiceTask的定义中,并没有体现出具有IoMapping属性的配置,此时我们可以查询 zeebeServiceTask 定义中的 extend 中的所有元素类型定义,看看有没有 IoMapping 配置。


当然:结果是没有找到


那么此时这个 IoMapping 属性该怎么配置到serviceTask节点上呢?


嗯~~~ 经过之前研究了一番他们的属性面板,发现这种情况下默认会挂载到 extensionElements 属性中,所以假设我们为一个ServiceTask节点添加了一个 IoMapping 配置的话,此时该节点的 businessObject 会变成这样:


// 只是提示内容格式,不要真的这么赋值哈
serviceTask.businessObject = {
    extensionElements: {
        $type: "bpmn:ExtensionElements",
        values: [
            {
                $type: "zeebe:IoMapping",
                inputParameters: [],
                outputParameters: []
            }
        ]
    }
}


在 xml 中体现为:


<bpmn:serviceTask id="Activity_0py009y">
  <bpmn:extensionElements>
    <zeebe:ioMapping></zeebe:ioMapping>
  </bpmn:extensionElements>
</bpmn:serviceTask>


1.3 Input 与 Output


现在我们在回过头来看一下 IoMapping 的两个 properties 属性配置,其参数配置都是自定义类型,一个是Input,一个是Output


而在上面的 JSON Schema 文件中Input 和 Output 都是继承的 InputOutputParameter 类型,具有两个 字符串格式 的参数 source 与 target

但是因为在 JSON Schema 文件中已经对 InputOutputParameter 重新定义成了两个类型 Input 与 Output,并且在 IoMapping 的定义中也没有使用 InputOutputParameter,所以我们在编写 js 代码的时候也要注意moddle.create 时传入的参数必须是 properties 配置中定义的那个类型名


那么此时我们给 IoMapping 的 inputParameters 与 outputParameters 设置值时,可以这么操作:


const moddle = modeler.get('moddle')
const input1 = moddle.create('zeebe:Input', {source: '=xxx1', target: 'target1'})
const input2 = moddle.create('zeebe:Input', {source: '=xxx2', target: 'target2'})
const output1 = moddle.create('zeebe:Output', {source: '=xxx3', target: 'target3'})
const ioMapping = moddle.create('zeebe:IoMapping', 
    {
        inputParameters: [input1, input2],
        outputParameters: [output1]
    }
)
// 需要根据情况判断 extensionElements 的存在情况,这里只是演示就不判断了,直接更新
modeling.updateModdleProperties(element, extensionElements,
    { values: [...extensionElements.get("values"), ioMapping] }
);


此时我们会得到一个类似这样的 xml


<bpmn:serviceTask id="Activity_0py009y">
  <bpmn:extensionElements>
    <zeebe:ioMapping>
      <zeebe:input source="=xxx1" target="InputVariable_3mqm1gd" />
      <zeebe:input source="=xxx2" target="InputVariable_3mqm1gd" />
      <zeebe:output source="=xxx3" target="OutputVariable_01h6ldb" />
    </zeebe:ioMapping>
  </bpmn:extensionElements>
  <bpmn:incoming>Flow_0nx7hug</bpmn:incoming>
</bpmn:serviceTask>


这里说明一下, xml 是通过官方的编辑器生成的,所以 target 字段会默认生成一个类似 hashID 的值;在实际项目中也可以参考这部分


最后


到此,通过 JSON Schema 分析元素属性结构的过程就基本结束了。总的来说,虽然可以通过这样的方式去分析出来,但是依旧没有通过到导入一个 xml 直接打印属性结构来的快。只是增加一个这样的分析过程,能加深我们对这个 JSON Schema 配置的理解,在后面需要配置和定义项目特殊的属性的时候,也能更加快速的配置出来。


目录
相关文章
|
6月前
|
Web App开发 前端开发
Chrome 浏览器插件 V3 版本 Manifest.json 文件中 Action 的类型(Types)、方法(Methods)和事件(Events)的属性和参数解析
Chrome 浏览器插件 V3 版本 Manifest.json 文件中 Action 的类型(Types)、方法(Methods)和事件(Events)的属性和参数解析
228 0
|
6月前
|
编解码 JavaScript 前端开发
TypeScript【第三方声明文件、自定义声明文件、tsconfig.json文件简介、tsconfig.json 文件结构与配置】(六)-全面详解(学习总结---从入门到深化)
TypeScript【第三方声明文件、自定义声明文件、tsconfig.json文件简介、tsconfig.json 文件结构与配置】(六)-全面详解(学习总结---从入门到深化)
319 0
|
14天前
|
JSON 关系型数据库 MySQL
MySQL JSON数据存储结构与操作
通过本文的介绍,我们了解了MySQL中JSON数据类型的基本操作、常用JSON函数、以及如何通过索引和优化来提高查询性能。JSON数据类型为存储和操作结构化数据提供了灵活性和便利性,在现代数据库应用中具有广泛的应用前景。希望本文对您在MySQL中使用JSON数据类型有所帮助。
29 0
|
2月前
|
JSON API 数据格式
使用Python发送包含复杂JSON结构的POST请求
使用Python发送包含复杂JSON结构的POST请求
|
3月前
|
JSON 数据处理 数据格式
Python中JSON结构数据的高效增删改操作
Python中JSON结构数据的高效增删改操作
|
4月前
|
JavaScript 前端开发 CDN
前端 JS 经典:package.json 属性详解
前端 JS 经典:package.json 属性详解
36 1
|
5月前
|
JSON C++ 数据格式
【VsCode】通过tasks.json中的problemMatcher属性的fileLocation子属性设定问题的输出内容
【VsCode】通过tasks.json中的problemMatcher属性的fileLocation子属性设定问题的输出内容
59 3
|
5月前
|
JSON 数据格式 微服务
.NET下 支持大小写不敏感的JSON Schema验证方法
有很多应用程序在验证JSON数据的时候用到了JSON Schema。 在微服务架构下,有时候各个微服务由于各种历史原因,它们所生成的数据对JSON Object属性名的大小写规则可能并不统一,它们需要消费的JSON数据的属性名可能需要大小写无关。 遗憾的是,目前的JSON Schema没有这方面的标准,标准中都是大小写敏感的。在类似上述情况下,这给使用JSON Schema进行数据验证造成了困难。
|
5月前
|
JSON JavaScript 数据格式
1.js动态的往json数据添加新属性和值 2.JSON 和 JS 对象互转 3.对象转化为数组
1.js动态的往json数据添加新属性和值 2.JSON 和 JS 对象互转 3.对象转化为数组
52 0
|
JSON C++ 数据格式
【VsCode】通过tasks.json中的problemMatcher属性的fileLocation子属性设定问题的输出内容
vscode 对于 json 文件的解析方式的开源代码部分. 摘录 文件目录设定部分的说明:
208 0