开发
bpmn-js
建模器,希望将
bpmn
数据格式转为
json
数据格式更加清晰的展示数据层次,以结果为导向分析需求,实现功能的思路有两种方式:
通过
bpmn-js
转化为
JS
数据对象,然后通过
JS
中提供的
JSON
模块转换为
json
数据
将
xml
解析成
dom
对象,通过
dom
对象转化为
json
格式数据
这里主要介绍上面两种方式,三方库转换如
xml-js
或
x2js
详细使用查看官方使用教程。
bpmn-js
中使用
bpmn-moddle
模块的
fromXML
方法解析成对象,然后通过
JSON
实现数据格式转换:
import BpmnModdle from 'bpmn-moddle';
const xml = `<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_Process_1709042749982" targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn:process id="Process_1709042749982" name="业务流程_1709042749982" isExecutable="true">
<bpmn:startEvent id="Event_19kysyf">
<bpmn:outgoing>Flow_1wrzkha</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:userTask id="Activity_0ajgzb4">
<bpmn:incoming>Flow_1wrzkha</bpmn:incoming>
<bpmn:outgoing>Flow_1cc5muf</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_1wrzkha" sourceRef="Event_19kysyf" targetRef="Activity_0ajgzb4" />
<bpmn:userTask id="Activity_13l6c40">
<bpmn:incoming>Flow_1cc5muf</bpmn:incoming>
<bpmn:outgoing>Flow_0gddaev</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_1cc5muf" sourceRef="Activity_0ajgzb4" targetRef="Activity_13l6c40" />
<bpmn:endEvent id="Event_0jyo997">
<bpmn:incoming>Flow_0gddaev</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0gddaev" sourceRef="Activity_13l6c40" targetRef="Event_0jyo997" />
<bpmn:textAnnotation id="TextAnnotation_0rrak2v" />
<bpmn:association id="Association_0p607id" sourceRef="Event_19kysyf" targetRef="TextAnnotation_0rrak2v" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1709042749982">
<bpmndi:BPMNShape id="TextAnnotation_0rrak2v_di" bpmnElement="TextAnnotation_0rrak2v">
<dc:Bounds x="300" y="240" width="100.00000762939453" height="30.000001907348633" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1wrzkha_di" bpmnElement="Flow_1wrzkha">
<di:waypoint x="218" y="350" />
<di:waypoint x="360" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1cc5muf_di" bpmnElement="Flow_1cc5muf">
<di:waypoint x="480" y="350" />
<di:waypoint x="622" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0gddaev_di" bpmnElement="Flow_0gddaev">
<di:waypoint x="742" y="350" />
<di:waypoint x="884" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_19kysyf_di" bpmnElement="Event_19kysyf">
<dc:Bounds x="182" y="332" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0ajgzb4_di" bpmnElement="Activity_0ajgzb4">
<dc:Bounds x="360" y="290" width="120" height="120" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_13l6c40_di" bpmnElement="Activity_13l6c40">
<dc:Bounds x="622" y="290" width="120" height="120" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0jyo997_di" bpmnElement="Event_0jyo997">
<dc:Bounds x="884" y="332" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Association_0p607id_di" bpmnElement="Association_0p607id">
<di:waypoint x="215" y="340" />
<di:waypoint x="326" y="270" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
const bpmnModdle = new BpmnModdle()
const jsonStr = await moddle.fromXML(xml)
const targetJson = JSON.stringify(jsonStr, null, 2)
使用DOMParser
DOMParser
是
JS
内置的一个可以将
XML
或者
HTML
文本信息解析成一个
DOM
对象的功能,那么我们就可以通过
DOMParser
文本解析成一个
DOM
对象,然后再将
DOM
对象转化为一个
JSON
数据。
解析成DOM对象
首先需要将xml文本转化为DOM对象,如下:
const xmlString = <?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_Process_1709042749982" targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn:process id="Process_1709042749982" name="业务流程_1709042749982" isExecutable="true">
<bpmn:startEvent id="Event_19kysyf">
<bpmn:outgoing>Flow_1wrzkha</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:userTask id="Activity_0ajgzb4">
<bpmn:incoming>Flow_1wrzkha</bpmn:incoming>
<bpmn:outgoing>Flow_1cc5muf</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_1wrzkha" sourceRef="Event_19kysyf" targetRef="Activity_0ajgzb4" />
<bpmn:userTask id="Activity_13l6c40">
<bpmn:incoming>Flow_1cc5muf</bpmn:incoming>
<bpmn:outgoing>Flow_0gddaev</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_1cc5muf" sourceRef="Activity_0ajgzb4" targetRef="Activity_13l6c40" />
<bpmn:endEvent id="Event_0jyo997">
<bpmn:incoming>Flow_0gddaev</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0gddaev" sourceRef="Activity_13l6c40" targetRef="Event_0jyo997" />
<bpmn:textAnnotation id="TextAnnotation_0rrak2v" />
<bpmn:association id="Association_0p607id" sourceRef="Event_19kysyf" targetRef="TextAnnotation_0rrak2v" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1709042749982">
<bpmndi:BPMNShape id="TextAnnotation_0rrak2v_di" bpmnElement="TextAnnotation_0rrak2v">
<dc:Bounds x="300" y="240" width="100.00000762939453" height="30.000001907348633" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1wrzkha_di" bpmnElement="Flow_1wrzkha">
<di:waypoint x="218" y="350" />
<di:waypoint x="360" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1cc5muf_di" bpmnElement="Flow_1cc5muf">
<di:waypoint x="480" y="350" />
<di:waypoint x="622" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0gddaev_di" bpmnElement="Flow_0gddaev">
<di:waypoint x="742" y="350" />
<di:waypoint x="884" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_19kysyf_di" bpmnElement="Event_19kysyf">
<dc:Bounds x="182" y="332" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0ajgzb4_di" bpmnElement="Activity_0ajgzb4">
<dc:Bounds x="360" y="290" width="120" height="120" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_13l6c40_di" bpmnElement="Activity_13l6c40">
<dc:Bounds x="622" y="290" width="120" height="120" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0jyo997_di" bpmnElement="Event_0jyo997">
<dc:Bounds x="884" y="332" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Association_0p607id_di" bpmnElement="Association_0p607id">
<di:waypoint x="215" y="340" />
<di:waypoint x="326" y="270" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
const domParser = new DOMParser(); // 创建DOMParser对象
const xmlElement = domParser.parseFromString(xmlString, 'text/xml') // 指定解析文本类型
解析DOM对象成JSON数据
获取到了
dom
对象后,我们可以通过便利
dom
对象层级解析拼接JSON数据:
// 解析element对象
function parseElement(element) {
const json ={}
if (element.hasChildNodes()) {
for (let i = 0; i < element.childNodes.length; i++) {
const child = element.childNodes[i];
if (child.nodeType === 1) {
if (child.hasChildNodes()) {
json[child.nodeName] = parseElement(child);
} else {
json[child.nodeName] = child.textContent;
return json
// 解析成json
const jsonString = parseElement(xmlElement)
格式化json数据
获取了json
数据后,为了美化json
数据的展示格式,我们需要将json
数据进行格式化处理:
const targetJson = JSON.stringify(jsonString , null, 2)
如下给出一个测试的html
代码及展示样式:
// test.html
<title>测试xml转json数据</title>
</head>
<pre id="code">
<script>
const xmlString = `<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_Process_1709042749982" targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn:process id="Process_1709042749982" name="业务流程_1709042749982" isExecutable="true">
<bpmn:startEvent id="Event_19kysyf">
<bpmn:outgoing>Flow_1wrzkha</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:userTask id="Activity_0ajgzb4">
<bpmn:incoming>Flow_1wrzkha</bpmn:incoming>
<bpmn:outgoing>Flow_1cc5muf</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_1wrzkha" sourceRef="Event_19kysyf" targetRef="Activity_0ajgzb4" />
<bpmn:userTask id="Activity_13l6c40">
<bpmn:incoming>Flow_1cc5muf</bpmn:incoming>
<bpmn:outgoing>Flow_0gddaev</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_1cc5muf" sourceRef="Activity_0ajgzb4" targetRef="Activity_13l6c40" />
<bpmn:endEvent id="Event_0jyo997">
<bpmn:incoming>Flow_0gddaev</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0gddaev" sourceRef="Activity_13l6c40" targetRef="Event_0jyo997" />
<bpmn:textAnnotation id="TextAnnotation_0rrak2v" />
<bpmn:association id="Association_0p607id" sourceRef="Event_19kysyf" targetRef="TextAnnotation_0rrak2v" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1709042749982">
<bpmndi:BPMNShape id="TextAnnotation_0rrak2v_di" bpmnElement="TextAnnotation_0rrak2v">
<dc:Bounds x="300" y="240" width="100.00000762939453" height="30.000001907348633" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1wrzkha_di" bpmnElement="Flow_1wrzkha">
<di:waypoint x="218" y="350" />
<di:waypoint x="360" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1cc5muf_di" bpmnElement="Flow_1cc5muf">
<di:waypoint x="480" y="350" />
<di:waypoint x="622" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0gddaev_di" bpmnElement="Flow_0gddaev">
<di:waypoint x="742" y="350" />
<di:waypoint x="884" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_19kysyf_di" bpmnElement="Event_19kysyf">
<dc:Bounds x="182" y="332" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0ajgzb4_di" bpmnElement="Activity_0ajgzb4">
<dc:Bounds x="360" y="290" width="120" height="120" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_13l6c40_di" bpmnElement="Activity_13l6c40">
<dc:Bounds x="622" y="290" width="120" height="120" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0jyo997_di" bpmnElement="Event_0jyo997">
<dc:Bounds x="884" y="332" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Association_0p607id_di" bpmnElement="Association_0p607id">
<di:waypoint x="215" y="340" />
<di:waypoint x="326" y="270" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
const domParser = new DOMParser(); // 创建DOMParser对象
const xmlElement = domParser.parseFromString(xmlString, 'text/xml') // 指定解析文本类型
// 解析element对象
function parseElement(element) {
const json ={}
if (element.hasChildNodes()) {
for (let i = 0; i < element.childNodes.length; i++) {
const child = element.childNodes[i];
if (child.nodeType === 1) {
if (child.hasChildNodes()) {
json[child.nodeName] = parseElement(child);
} else {
json[child.nodeName] = child.textContent;
return json
// 解析成json
const jsonString = parseElement(xmlElement)
const targetJson = JSON.stringify(jsonString , null, 2)
document.write(targetJson)
</script>
</body>
</html>
显示效果如下:
赞(0) 打赏