如何自己实现一个丝滑的流程图绘制工具(五)bpmn的xml和json互转
背景
因为服务端给的数据并不是xml,而且服务端要拿的数据是json,所以我们只能xml和json互转,来完成和服务端的对接
xml转json
import XML from './config/jsonxml.js'/*** xml转为json* @param {*} xml*/xmlToJson(xml) {const xotree = new XML.ObjTree()const jsonData = xotree.parseXML(xml)return jsonData},
jsonxml.js
const XML = function() {}// constructorXML.ObjTree = function() {return this
}// class variablesXML.ObjTree.VERSION = '0.23'// object prototypeXML.ObjTree.prototype.xmlDecl = '<?xml version="1.0" encoding="UTF-8" ?>\n'
XML.ObjTree.prototype.attr_prefix = '-'// method: parseXML( xmlsource )XML.ObjTree.prototype.parseXML = function(xml) {let rootif (window.DOMParser) {var xmldom = new DOMParser()// xmldom.async = false; // DOMParser is always sync-modeconst dom = xmldom.parseFromString(xml, 'application/xml')if (!dom) returnroot = dom.documentElement} else if (window.ActiveXObject) {xmldom = new ActiveXObject('Microsoft.XMLDOM')xmldom.async = falsexmldom.loadXML(xml)root = xmldom.documentElement}if (!root) returnreturn this.parseDOM(root)
}// method: parseHTTP( url, options, callback )XML.ObjTree.prototype.parseHTTP = function(url, options, callback) {const myopt = {}for (const key in options) {myopt[key] = options[key] // copy object}if (!myopt.method) {if (typeof myopt.postBody === 'undefined' &&typeof myopt.postbody === 'undefined' &&typeof myopt.parameters === 'undefined') {myopt.method = 'get'} else {myopt.method = 'post'}}if (callback) {myopt.asynchronous = true // async-modeconst __this = thisconst __func = callbackconst __save = myopt.onCompletemyopt.onComplete = function(trans) {let treeif (trans && trans.responseXML && trans.responseXML.documentElement) {tree = __this.parseDOM(trans.responseXML.documentElement)}__func(tree, trans)if (__save) __save(trans)}} else {myopt.asynchronous = false // sync-mode}let transif (typeof HTTP !== 'undefined' && HTTP.Request) {myopt.uri = urlvar req = new HTTP.Request(myopt) // JSANif (req) trans = req.transport} else if (typeof Ajax !== 'undefined' && Ajax.Request) {var req = new Ajax.Request(url, myopt) // ptorotype.jsif (req) trans = req.transport}if (callback) return transif (trans && trans.responseXML && trans.responseXML.documentElement) {return this.parseDOM(trans.responseXML.documentElement)}
}// method: parseDOM( documentroot )XML.ObjTree.prototype.parseDOM = function(root) {if (!root) returnthis.__force_array = {}if (this.force_array) {for (let i = 0; i < this.force_array.length; i++) {this.__force_array[this.force_array[i]] = 1}}let json = this.parseElement(root) // parse root nodeif (this.__force_array[root.nodeName]) {json = [json]}if (root.nodeType != 11) {// DOCUMENT_FRAGMENT_NODEconst tmp = {}tmp[root.nodeName] = json // root nodeNamejson = tmp}return json
}// method: parseElement( element )XML.ObjTree.prototype.parseElement = function(elem) {// COMMENT_NODEif (elem.nodeType == 7) {return}// TEXT_NODE CDATA_SECTION_NODEif (elem.nodeType == 3 || elem.nodeType == 4) {const bool = elem.nodeValue.match(/[^\x00-\x20]/)if (bool == null) return // ignore white spacesreturn elem.nodeValue}let retvalconst cnt = {}// parse attributesif (elem.attributes && elem.attributes.length) {retval = {}for (var i = 0; i < elem.attributes.length; i++) {var key = elem.attributes[i].nodeNameif (typeof key !== 'string') continuevar val = elem.attributes[i].nodeValueif (!val) continuekey = this.attr_prefix + keyif (typeof cnt[key] === 'undefined') cnt[key] = 0cnt[key]++this.addNode(retval, key, cnt[key], val)}}// parse child nodes (recursive)if (elem.childNodes && elem.childNodes.length) {let textonly = trueif (retval) textonly = false // some attributes existsfor (var i = 0; i < elem.childNodes.length && textonly; i++) {const ntype = elem.childNodes[i].nodeTypeif (ntype == 3 || ntype == 4) continuetextonly = false}if (textonly) {if (!retval) retval = ''for (var i = 0; i < elem.childNodes.length; i++) {retval += elem.childNodes[i].nodeValue}} else {if (!retval) retval = {}for (var i = 0; i < elem.childNodes.length; i++) {var key = elem.childNodes[i].nodeNameif (typeof key !== 'string') continuevar val = this.parseElement(elem.childNodes[i])if (!val) continueif (typeof cnt[key] === 'undefined') cnt[key] = 0cnt[key]++this.addNode(retval, key, cnt[key], val)}}}return retval
}// method: addNode( hash, key, count, value )XML.ObjTree.prototype.addNode = function(hash, key, cnts, val) {if (this.__force_array[key]) {if (cnts == 1) hash[key] = []hash[key][hash[key].length] = val // push} else if (cnts == 1) {// 1st siblinghash[key] = val} else if (cnts == 2) {// 2nd siblinghash[key] = [hash[key], val]} else {// 3rd sibling and morehash[key][hash[key].length] = val}
}// method: writeXML( tree )XML.ObjTree.prototype.writeXML = function(tree) {const xml = this.hash_to_xml(null, tree)return this.xmlDecl + xml
}// method: hash_to_xml( tagName, tree )XML.ObjTree.prototype.hash_to_xml = function(name, tree) {const elem = []const attr = []for (const key in tree) {if (!tree.hasOwnProperty(key)) continueconst val = tree[key]if (key.charAt(0) != this.attr_prefix) {if (typeof val === 'undefined' || val == null) {elem[elem.length] = `<${key} />`} else if (typeof val === 'object' && val.constructor == Array) {elem[elem.length] = this.array_to_xml(key, val)} else if (typeof val === 'object') {elem[elem.length] = this.hash_to_xml(key, val)} else {elem[elem.length] = this.scalar_to_xml(key, val)}} else {attr[attr.length] = ` ${key.substring(1)}="${this.xml_escape(val)}"`}}const jattr = attr.join('')let jelem = elem.join('')if (typeof name === 'undefined' || name == null) {// no tag} else if (elem.length > 0) {if (jelem.match(/\n/)) {jelem = `<${name}${jattr}>\n${jelem}</${name}>\n`} else {jelem = `<${name}${jattr}>${jelem}</${name}>\n`}} else {jelem = `<${name}${jattr} />\n`}return jelem
}// method: array_to_xml( tagName, array )XML.ObjTree.prototype.array_to_xml = function(name, array) {const out = []for (let i = 0; i < array.length; i++) {const val = array[i]if (typeof val === 'undefined' || val == null) {out[out.length] = `<${name} />`} else if (typeof val === 'object' && val.constructor == Array) {out[out.length] = this.array_to_xml(name, val)} else if (typeof val === 'object') {out[out.length] = this.hash_to_xml(name, val)} else {out[out.length] = this.scalar_to_xml(name, val)}}return out.join('')
}// method: scalar_to_xml( tagName, text )XML.ObjTree.prototype.scalar_to_xml = function(name, text) {if (name == '#text') {return this.xml_escape(text)}return `<${name}>${this.xml_escape(text)}</${name}>\n`
}// method: xml_escape( text )XML.ObjTree.prototype.xml_escape = function(text) {return `${text}`.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')
}export default XML
json 转为xml
const getIncoming = (id, data) => {return data.filter(item => item.targetRef === id).map(items => items.id)
}
const getOutGoing = (id, data) => {return data.filter(item => item.sourceRef === id).map(items => items.id)
}
const getLabel = (data, labelStyle) => {const keyWord = ['isBold', 'isItalic', 'isStrikeThrough', 'isUnderline', 'fontFamily', 'size']const arr = data.filter(item => {return keyWord.find(key => {return key in labelStyle})})return arr.map(item => {const obj = {}keyWord.forEach(key => {if (labelStyle[key]) {obj[key === 'fontFamily' ? 'name' : key] = labelStyle[key] || ''}})return {'-id': item.id,'omgdc:Font': obj}})
}
export function convertJsonToBpmn(jsonData) {if (!jsonData || !Object.keys(jsonData).length) return {}const result = {definitions: {'-xmlns': 'http://www.omg.org/spec/BPMN/20100524/MODEL','-xmlns:bpmndi': 'http://www.omg.org/spec/BPMN/20100524/DI','-xmlns:omgdi': 'http://www.omg.org/spec/DD/20100524/DI','-xmlns:omgdc': 'http://www.omg.org/spec/DD/20100524/DC','-xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance','-xmlns:bioc': 'http://bpmn.io/schema/bpmn/biocolor/1.0','-xmlns:color': 'http://www.omg.org/spec/BPMN/non-normative/color/1.0','-id': 'sid-38422fae-e03e-43a3-bef4-bd33b32041b2','-targetNamespace': 'http://bpmn.io/bpmn','-exporter': 'bpmn-js (https://demo.bpmn.io)','-exporterVersion': '5.1.2',process: {'-id': 'Process_1','-isExecutable': 'true',task: [],sequenceFlow: []},'bpmndi:BPMNDiagram': {'-id': 'BpmnDiagram_1','bpmndi:BPMNPlane': {'-id': 'BpmnPlane_1','-bpmnElement': 'Process_1','bpmndi:BPMNShape': [],'bpmndi:BPMNEdge': []}},'bpmndi:BPMNLabelStyle': {}}}// Convert tasksjsonData.nodeLists.forEach(task => {const taskId = task.config.idconst incoming = getIncoming(taskId, jsonData.lines)const outGoing = getOutGoing(taskId, jsonData.lines)const obj = {'-id': taskId}if (incoming.length > 1) {obj.incoming = incoming} else if (incoming.length === 1) {obj.incoming = incoming[0]}if (outGoing.length > 1) {obj.outgoing = outGoing} else if (outGoing.length === 1) {obj.outgoing = outGoing[0]}result.definitions.process.task.push(obj)const { x, y, width, height, labelStyle } = task.configconst element = {'-id': `${taskId}_di`,'-bpmnElement': taskId,'omgdc:Bounds': {'-x': x,'-y': y,'-width': width,'-height': height},'bpmndi:BPMNLabel': {}}if (labelStyle && Object.keys(labelStyle).length) {const { x, y, width, height, id } = labelStyleelement['bpmndi:BPMNLabel']['-labelStyle'] = idelement['bpmndi:BPMNLabel']['omgdc:Bounds'] = {'-x': x,'-y': y,'-width': width,'-height': height}result.definitions['bpmndi:BPMNLabelStyle'] = getLabel(jsonData.nodeLists, labelStyle)}// Convert BPMN shapesresult.definitions['bpmndi:BPMNDiagram']['bpmndi:BPMNPlane']['bpmndi:BPMNShape'].push(element)})// Convert sequence flowsjsonData.lines.forEach(line => {const sequenceFlowId = line.idconst sourceRef = line.sourceRefconst targetRef = line.targetRefresult.definitions.process.sequenceFlow.push({'-id': `${sequenceFlowId}`,'-name': line.name,'-sourceRef': sourceRef,'-targetRef': targetRef})// Convert BPMN edgesresult.definitions['bpmndi:BPMNDiagram']['bpmndi:BPMNPlane']['bpmndi:BPMNEdge'].push({'-id': `${sequenceFlowId}_di`,'-bpmnElement': sequenceFlowId,'omgdi:waypoint': line.point.map(p => {return { '-x': p.x, '-y': p.y }}),'bpmndi:BPMNLabel': {'omgdc:Bounds': {'-x': line.x,'-y': line.y,'-width': line.width,'-height': line.height}}})})return result
}
相关文章:
如何自己实现一个丝滑的流程图绘制工具(五)bpmn的xml和json互转
背景 因为服务端给的数据并不是xml,而且服务端要拿的数据是json,所以我们只能xml和json互转,来完成和服务端的对接 xml转json import XML from ./config/jsonxml.js/*** xml转为json* param {*} xml*/xmlToJson(xml) {const xotree new X…...

mysql--数据库的操作
数据库,是数据存储的最大单元。 1 创建数据库 create database mydatabase; 每次创建数据库的时候,都会多一个文件夹,关系型数据库是存储在磁盘当中的,所以这时候可以查看新建的数据库 2 指定字符集 MySQL中的字符集转换过程 制…...

kafka--技术文档--架构体系
架构体系 Kafka的架构体系包括以下几个部分: Producer. 消息生产者,就是向Kafka broker发送消息的客户端。Broker. 一台Kafka服务器就是一个Broker。一个集群由多个Broker组成。一个Broker可以容纳多个Topic。Topic. 可以理解为一个队列,一…...

ctfshow web入门 web103-web107
1.web103 和102一样 payload: v2115044383959474e6864434171594473&v3php://filter/writeconvert.base64-decode/resource1.php post v1hex2bin2.web104 值只要一样就可以了 payload: v21 post v113.web105 考查的是$$变量覆盖,die可以带出数据,输出一条消息…...

前端工程化之模块化
模块化的背景 前端模块化是一种标准,不是实现理解模块化是理解前端工程化的前提前端模块化是前端项目规模化的必然结果 什么是前端模块化? 前端模块化就是将复杂程序根据规范拆分成若干模块,一个模块包括输入和输出。而且模块的内部实现是私有的&…...

文件服务器实现方式汇总
hello,伙伴们,大家好,今天这一期shigen来给大家推荐几款可以一键实现文件浏览器的工具,让你轻松的实现文件服务器和内网的文件传输、预览。 基于node 本次推荐的是http-server, 它的githuab地址是:http-s…...
ChatGPT计算机科学与技术专业的本科毕业论文,2000字。论文查重率低于30%。
目录 摘要 Abstract 绪论 1.1 研究背景 1.2 研究目的和意义 2.1 ChatGPT技术概述 2.2 ChatGPT技术的优缺点分析 2.2.1 优点 2.2.2 缺点 摘要 本论文围绕ChatGPT展开,介绍了该技术的发展历程、特点及应用,分析了该技术的优缺点,提出了…...

【Winform学习笔记(八)】通过委托实现跨窗体传值
通过委托实现跨窗体传值 前言正文1、委托及事件2、通过委托实现跨窗体传值的步骤1.在子窗体中定义委托2.在子窗体中声明一个委托类型的事件3.调用委托类型事件4.在实例化子窗体后,子窗体订阅事件接受方法5.实现具体的事件 3、具体示例4、完整代码5、实现效果 前言 …...

Windows用户如何安装Cpolar
目录 概述 什么是cpolar? cpolar可以用在哪些场景? 1. 注册cpolar帐号 1.1 访问官网站点 2. 下载Windows版本cpolar客户端 2.1 下载并安装 2.2 安装完验证 3. token认证 3.1 将token值保存到默认的配置文件中 3.2 创建一个随机url隧道&#x…...
C++最易读手撸神经网络两隐藏层(任意Nodes每层)梯度下降230820a
这是史上最简单、清晰,最易读的…… C语言编写的 带正向传播、反向传播(Forward ……和Back Propagation)……任意Nodes数的人工神经元神经网络……。 大一学生、甚至中学生可以读懂。 适合于,没学过高数的程序员……照猫画虎编写人工智能、…...

机器学习理论笔记(二):数据集划分以及模型选择
文章目录 1 前言2 经验误差与过拟合3 训练集与测试集的划分方法3.1 留出法(Hold-out)3.2 交叉验证法(Cross Validation)3.3 自助法(Bootstrap) 4 调参与最终模型5 结语 1 前言 欢迎来到蓝色是天的机器学习…...

10*1000【2】
知识: -----------金融科技背后的技术---------------- -------------三个数字化趋势 1.数据爆炸:internet of everything(iot);实时贡献数据;公有云服务->提供了灵活的计算和存储。 2.由计算能力驱动的&#x…...
“探秘JS加密算法:MD5、Base64、DES/AES、RSA你都知道吗?”
目录 1、什么是JS、JS反爬是什么?JS逆向是什么? 2、JS逆向的大致流程 3、逆向的环境搭建 3.1、安装node.js 3.2、安装js代码调试工具(vscode) 3.3、安装PyExecJs模块 4、JS常见加密算法 4.1、Base64算法 4.2、MD5算法 4.3、DES/AES算法 4.2.2 AES与DES的…...

Spark项目Java和Scala混合打包编译
文章目录 项目结构Pom完整文件编译查看 实际开发用有时候引用自己写的一些java工具类,但是整个项目是scala开发的spark程序,在项目打包时需要考虑到java和scala混合在一起编译。 今天看到之前很久之前写的一些打包编译文章,发现很多地方不太对…...

深度学习处理文本(NLP)
文章目录 引言1. 反向传播1.1 实例流程实现1.2 前向传播1.3 计算损失1.4 反向传播误差1.5 更新权重1.6 迭代1.7 BackPropagation & Adam 代码实例 2. 优化器 -- Adam2.1 Adam解析2.2 代码实例 3. NLP任务4. 神经网络处理文本4.1 step1 字符数值化4.2 step 2 矩阵转化为向量…...

汽车电子笔记之:AUTOSAR方法论及基础概念
目录 1、AUTOSAR方法论 2、AUTOSAR的BSW 2.1、MCAL 2.2、ECU抽象层 2.3、服务层 2.4、复杂驱动 3、AUTOSAR的RTE 4、AUTOSAR的应用层 4.1、SWC 4.2、AUTOSAR的通信 4.3、AUTOSAR软件接口 1、AUTOSAR方法论 AUTOSAR为汽车电子软件系统开发过程定义了一套通用的技术方法…...

鼠标拖拽盒子移动
目录 需求思路代码页面展示【补充】纯js实现 需求 浮动的盒子添加鼠标拖拽功能 思路 给需要拖动的盒子添加鼠标按下事件鼠标按下后获取鼠标点击位置与盒子边缘的距离给 document 添加鼠标移动事件鼠标移动过程中,将盒子的位置进行重新定位侦听 document 鼠标弹起&a…...
AUTOSAR从入门到精通-【应用篇】面向车联网的车辆攻击方法及入侵检测
目录 前言 国内外研究现状 (1)车辆攻击方法的研究 (2)车辆安全防护技术的研究...

0101prox-shardingsphere-中间件
1 启动ShardingSphere-Proxy 1.1 获取 目前 ShardingSphere-Proxy 提供了 3 种获取方式: 二进制发布包DockerHelm 这里我们使用Docker安装。 1.2 使用Docker安装 step1:启动Docker容器 docker run -d \ -v /Users/gaogzhen/data/docker/shardings…...
FactoryBean和BeanFactory:Spring IOC容器的两个重要角色简介
目录 一、简介 二、BeanFactory 三、FactoryBean 四、区别 五、使用场景 总结 一、简介 在Spring框架中,IOC(Inversion of Control)容器是一个核心组件,它负责管理和配置Java对象及其依赖关系,实现了控制反转&a…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...

数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...