def _fix_call_activities_signavio(self, bpmn, filename):
for node in xpath_eval(bpmn)("<STR_LIT>"):<EOL><INDENT>calledElement = node.get('<STR_LIT>', None)<EOL>if not calledElement:<EOL><INDENT>signavioMetaData = xpath_eval(node, extra_ns={<EOL>'<STR_LIT>': SIGNAVIO_NS})(<EOL>'<STR_LIT>')<EOL>if not signavioMetaData:<EOL><INDENT>raise ValidationException(<EOL>'<STR_LIT>',<EOL>node=node, filename=filename)<EOL><DEDENT>subprocess_reference = one(signavioMetaData).get('<STR_LIT>')<EOL>matches = []<EOL>for b in list(self.bpmn.values()):<EOL><INDENT>for p in xpath_eval(b)("<STR_LIT>"):<EOL><INDENT>if (p.get('<STR_LIT:name>', p.get('<STR_LIT:id>', None)) ==<EOL>subprocess_reference):<EOL><INDENT>matches.append(p)<EOL><DEDENT><DEDENT><DEDENT>if not matches:<EOL><INDENT>raise ValidationException(<EOL>"<STR_LIT>" %<EOL>subprocess_reference, node=node, filename=filename)<EOL><DEDENT>if len(matches) != <NUM_LIT:1>:<EOL><INDENT>raise ValidationException(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" % subprocess_reference, node=node,<EOL>filename=filename)<EOL><DEDENT>node.set('<STR_LIT>', matches[<NUM_LIT:0>].get('<STR_LIT:id>'))<EOL><DEDENT><DEDENT>
Signavio produces slightly invalid BPMN for call activity nodes... It
is supposed to put a reference to the id of the called process in to
the calledElement attribute. Instead it stores a string (which is the
name of the process - not its ID, in our interpretation) in an
extension tag.

This code gets the name of the 'subprocess reference', finds a process
with a matching name, and sets the calledElement attribute to the id of
the process.