添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

开发 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) 打赏
    转载请附上原文出处链接:胖蔡说技术 » bpmn-js中实现xml数据转为json数据