Export to XML only some elements


#1

Hi again!

I need some help with this task. I have to export to XML my bpmn diagram, but I only need some elements (ServiceTasks).

Could you help me please?

In this moment, I think I have to change this part of the code:

function saveDiagram(done) {

  bpmnModeler.saveXML({ format: true }, function(err, xml) {
    done(err, xml);
  });
}

Thanks a lot.


#2

What is the use case? Can you provide more context?


#3

Yes, of course. Sorry for that, I’m new at this.

I have developed a bpmn modeler with a new element. I use the “ServiceTask” and modify it to get it.

In this step I need to develop a function that give a xml file with all ServiceTask elements from the model.

I was looking for and finally I found this function in bpmn-js/Viewer.js:

Viewer.prototype.saveXML = function(options, done) {

  if (!done) {
    done = options;
    options = {};
  }

  var definitions = this._definitions;

  if (!definitions) {
    return done(new Error('no definitions loaded'));
  }
  this._moddle.toXML(definitions, options, done);
};

I’m thinking about “definitions” but I don’t know how to extract only what I need.


#4

What is the use-case of only exporting service tasks? Do you still want to have a valid BPMN diagram? Do you actually want the XML or just a way of accessing the service tasks?


#5

I’m developing a API that receive a XML file and transform it to a json file.

For this, I need export XML file from the modeler with only the ServiceTask elements.


#6

So you want to create a JSON file with information about all service tasks of a diagram? How would you extract this information from the XML? Why wouldn’t you get this information directly without previously exporting the diagram?


#7

This is a good solution. But I have the same problem; I don’t know how to extract the information as JSON format or get it directly.

Edit:

I just have developed this function:

function saveJSON(done) {
  var definitions = bpmnModeler.get('canvas').getRootElement().businessObject.$parent;
  var json = (JSON.stringify(definitions));
  bpmnModeler.saveXML({ format: true }, function(err, xml) {
    done(err, json);
  });
}

But this return a json file with all the diagram. How can I filter it with only ServiceTask?


#8

You can not simply stringify the definitions depending on what you want to do with the JSON string afterwards. Please explain, what exactly you expect the JSON to look like.


#9

Solved!

Here my code:

function saveJSON(done) {
  var definitions = bpmnModeler.get('canvas').getRootElement().businessObject.$parent;
  var rootElements = definitions.rootElements || [];
  var json = (JSON.stringify(definitions));
  var json2 = (JSON.parse(json));
  var serviceTasks = new JefNode(json2).filter(function(element) {
    if (element.key === '$type') {
      if(element.value === 'bpmn:ServiceTask'){
        return (JSON.stringify(element.parent.value));
      }
    } 
  });
  bpmnModeler.saveXML({ format: false }, function(err, xml) {
    done(err, serviceTasks);
  });
}

Now, I need to connect the bpmn modeler with the API. I need to catch the data with the API and save them into mongoDB.


#10

This solution looks very complicated. If you simply want to put all service tasks into a JSON string without caring about importing them again later you can do:

function saveJSON() {
  const elementRegistry = bpmnModeler.get('elementRegistry');

  const serviceTasks = elementRegistry.filter(e => e.type === 'bpmn:ServiceTask');

  const serviceTaskBusinessObjects = serviceTasks.map(e => e.businessObject);

  return JSON.stringify(serviceTaskBusinessObjects);
}

There’s no need for an additional library. Why are you calling saveXML at the end?


#11

Okey, I’m going to try it.
I called saveXML because I need the button get a download file. I don’t know how to do this without using saveXML method.


#12

What are you trying to achieve? Downloading the XML? If so, then wouldn’t the saveJSON function be the wrong place to do so?


#13

Hi again, this solution is works but now I need to add to JSON file the “id” attribute for each subtasks of the serviceTask.

17


#14

What are you referring to as a subtask?


#15

Sorry, I mean the id attribute of all the tasks in the outgoing array in the serviceTasks.

I need export a JSON with all attributes of serviceTask elements (already done) + a list with the ids of your tasks outgoing.


#16

Shouldn’t that be pretty straight forward? Since the outgoing property is not enumerable it wont be stringified so you have to take care of it seperately:

function saveJSON() {
  const elementRegistry = bpmnModeler.get('elementRegistry');

  const serviceTasks = elementRegistry.filter(e => e.type === 'bpmn:ServiceTask');

  const serviceTaskBusinessObjects = serviceTasks.map(e => e.businessObject);

  const serviceTaskBusinessObjects = serviceTasks.map(e => {
    const businessObject = e.businessObject;

    // clone the business object using lodash's clone function since we don't want to mutate the actual business object
    const copy = _.clone(businessObject);

    copy.outgoing = businessObject.outgoing.map(e => e.id);

    return copy;
  });


  return JSON.stringify(serviceTaskBusinessObjects);
}

#17

Thank you very much Philip, this solution it’s works for me :slight_smile: