Search code examples
bpmnbpmn.io

How to specify XML element names in bpmn-js


If I define a moddle file with bpmn-js like this

    {
        name: "thisArgument",
        superClass: [
            "Element"
        ],
        properties: []
    },
    {
        name: "myData",
        superClass: [
            "Element"
        ],
        properties: [
            {
                name: "argument",
                type: "thisArgument"
            }
        ]
    },

Then the resulting XML (when I call saveXML) will have an element called thisArgument, despite the fact that the name is "argument". First, is that a bug? If not, how do I control the output so that the XML contains argument rather than thisArgument? I've searched the docs and examples but can't find how to do this.

The only workaround I found was to make it type: "argument" and then define argument with a superClass of thisArgument and no extra properties (essentially making an alias). However, that only works if all instances of argument are identical. Eg. if the XML needed to be

<A><argument/></A>
<B><argument/></B>

where the argument in A has a different shape than the argument in B, then there would be a conflict since I can't define argument twice.


Solution

  • I can sort of answer my own question. I found this serialize option and experimented, and it mostly does what I want, but sometimes it adds an unwanted xsi:type="originalType" attribute and sometimes it doesn't. Maybe it depends on isBody but I'm not sure. If anyone knows the details of how it works, please reply.

    properties: [
        {
            name: "argument",
            type: "thisArgument",
            xml: {
                serialize: "xsi:type"
            },
        }
    ]
    

    The closest thing I found to documentation on it is https://forum.bpmn.io/t/bpmn-json-documentation/1304 which describes it as "additional meta-data impecting XML serialization of a type", so I'd appreciate any extra details anyone can supply.

    Update: The docs don't mention this, but it turns out that serialize: "property" is exactly what I need. This does the same as serialize: "xsi:type" but doesn't add the xsi:type attribute.

        xml: {
            serialize: "property"
        },
    

    I found this by hunting the code in one of the related packages, moddle-xml.

    In write.js, there's code that looks for the xsi:type or property entry:

      // allow serialization via type
      // rather than element name
      var asType = serializeAsType(p),
          asProperty = serializeAsProperty(p);
    

    In the same file, I found some code that appears to explain why the xsi:type didn't always show up, too:

      // only serialize xsi:type if necessary
      if (descriptor.name === this.propertyDescriptor.type) {
            return attributes;
      }