胖蔡说技术
随便扯扯

bpmn-js中实现xml数据转为json数据

开发bpmn-js建模器,希望将bpmn数据格式转为json数据格式更加清晰的展示数据层次,以结果为导向分析需求,实现功能的思路有两种方式:

  • 通过bpmn-js转化为JS数据对象,然后通过JS中提供的JSON模块转换为json数据
  • xml解析成dom对象,通过dom对象转化为json格式数据
  • 三方库

这里主要介绍上面两种方式,三方库转换如xml-jsx2js详细使用查看官方使用教程。

对象转换

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

DOMParserJS内置的一个可以将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
<html>
<head>
<title>测试xml转json数据</title>
</head>
<body>
<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>

</pre>
</body>
</html>

显示效果如下:

赞(0) 打赏
转载请附上原文出处链接:胖蔡说技术 » bpmn-js中实现xml数据转为json数据
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏