Export to XML only some elements

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.

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

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.

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?

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.

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?

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?

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.

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.

1 Like

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?

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.

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

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

What are you referring to as a subtask?

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.

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);
}
3 Likes

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