Cannot get correct elementTypeName in reader.js from moddle-xml

In reader.js(405-407)

if (pkg) {
    elementTypeName = nameNs.prefix + ':' + aliasToName(nameNs.localName, descriptor.$pkg);
    elementType = model.getType(elementTypeName);

I got a error when import diagram with customized property ‘import’, it find ‘import’ defined in bpmn.json not in customized.json.

When I changed

elementTypeName = nameNs.prefix + ':' + aliasToName(nameNs.localName, descriptor.$pkg);

as

elementTypeName = nameNs.prefix + ':' + aliasToName(nameNs.localName, pkg);

then, everything is ok.

Is this a mistake?

Please give use more details on the stuff you are doing.

One way to do this is to provide a failing test case for your scenario as a PR.

Test case pushed to moddle-xml (Forked) , and code as below:

Data type definition.json:

{
  "name": "Definitions",
  "uri": "http://definitions",
  "prefix": "d",
  "xml" : {
    "tagAlias": "lowerCase"
  },
  "types": [
    {
      "name": "Definitions",
      "properties": [
        {
          "name": "import",
          "type": "Import",
          "isMany": true
        },
        {
          "name": "extensionElements",
          "type": "ExtensionElements"
        }
      ]
    },
    {
      "name": "Import",
      "properties": [
        {
          "name": "name",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "ExtensionElements",
      "properties": [
        {
          "name": "valueRef",
          "isAttr": true,
          "isReference": true,
          "type": "Element"
        },
        {
          "name": "values",
          "type": "Element",
          "isMany": true
        },
        {
          "name": "extensionAttributeDefinition",
          "type": "ExtensionAttributeDefinition",
          "isAttr": true,
          "isReference": true
        }
      ]
    },
    {
      "name": "ExtensionAttributeDefinition",
      "properties": [
        {
          "name": "name",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "type",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "isReference",
          "default": false,
          "isAttr": true,
          "type": "Boolean"
        },
        {
          "name": "extensionDefinition",
          "type": "ExtensionDefinition",
          "isAttr": true,
          "isReference": true
        }
      ]
    }
  ]
}

Data type definition-external.json:

{
  "name": "Definitions 2",
  "uri": "http://definitions2",
  "prefix": "d2",
  "associations": [],
  "types": [
    {
      "name": "import",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "name",
          "type": "String",
          "isAttr": true
        }
      ]
    }
  ]
}

Test case:

      it('collection / xsi:type / with same name from default ns and external ns', function(done) {

        var datatypeModel = createModel(['definition', 'definition-external']);

        // given
        var reader = new Reader(datatypeModel);
        var rootHandler = reader.handler('d:Definitions');

        var xml =
          '<d:Definitions xmlns:d="http://definitions" xmlns:d2="http://definitions2">' +
          '<d:import name="clazzA" />' +
          '<d:import name="clazzB" />' +
          '<d:extensionElements>' +
          '<d2:import name="clazzC" />' +
          '<d2:import name="clazzD" />' +
          '</d:extensionElements>' +
          '</d:Definitions>';

        // when
        reader.fromXML(xml, rootHandler, function(err, result) {

          if (err) {
            return done(err);
          }

          // then
          expect(result).to.jsonEqual({
            $type: 'd:Definitions',
            import: [
              {
                $type: 'd:Import',
                name: 'clazzA'
              },
              {
                $type: 'd:Import',
                name :'clazzB'
              }
            ],
            extensionElements: {
              $type: "d:ExtensionElements",
              values: [{
                $type: 'd2:import',
                name: 'clazzC'
              },
                {
                  $type: 'd2:import',
                  name: 'clazzD'
                }
              ]
            }
          });

          done();
        });
      });

When ‘elementTypeName = nameNs.prefix + ‘:’ + aliasToName(nameNs.localName, descriptor.$pkg);’, get failure:

  98 passing (247ms)
  1 failing

missing namespace information for  foo:bar = BAR on Base { '$type': 'e:Root' } [Error: no namespace uri given for prefix <foo>]
  1) Reader should import data types collection / xsi:type / with same name from other namespace and default ns:
     Error: unparsable content <d2:import> detected
	line: 0
	column: 175
	nested error: unknown type <d2:Import>
      at error (lib/reader.js:99:10)
      at Object.handleOpen [as onopentag] (lib/reader.js:686:15)
      at emit (node_modules/sax/lib/sax.js:615:33)
      at emitNode (node_modules/sax/lib/sax.js:620:3)
      at openTag (node_modules/sax/lib/sax.js:801:3)
      at Object.write (node_modules/sax/lib/sax.js:1181:11)
      at lib/reader.js:708:14
      at null._onTimeout (node_modules/lodash/internal/baseDelay.js:18:39)



Warning: Task "mochaTest:test" failed. Use --force to continue.

Aborted due to warnings.

then ‘elementTypeName = nameNs.prefix + ‘:’ + aliasToName(nameNs.localName, pkg);’, all passing:

  99 passing (286ms)


Done, without errors.

It tells you exactly what is wrong. You did not define the type d2:Import.

Currently moddle assumes types are defined upper case. That means you’d need to fix your d2 definition for d2:import:

...
 {
   "name": "Import",
   "superClass": [
     "Element"
   ],
   ...

With that change the test failure you mention is gone.

If d2:import required not d2:Import, how to define data type?

Can you elaborate on this?

Actually, I need to import bpmn definition like this snippet:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" xmlns:drools="http://www.jboss.org/drools" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
  <bpmn2:process id="Evaluation" name="Evaluation" isExecutable="true">
    <bpmn2:extensionElements>
      <drools:import name="com.example.model.User" />
    </bpmn2:extensionElements>
    <bpmn2:startEvent id="StartEvent_1">
      <bpmn2:outgoing>SequenceFlow_0mk6ujy</bpmn2:outgoing>
    </bpmn2:startEvent>
    ...
  </bpmn2:process>
</bpmn2:definitions>

Attention to '<drools:import name="com.example.model.User" />', must be ‘drools:import’ not ‘drools:Import’. Because of element ‘bpmn:import’ in type ‘bpmn:Import’ has been defined in bpmn.json, So when I defined ‘drools:import’ in drools.json as:

{
  "name": "DROOLS",
  "uri": "http://www.jboss.org/drools",
  "prefix": "drools",
  "associations": [],
  "types": [
    {
      "name": "import",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "name",
          "type": "String",
          "isAttr": true
        }
      ]
    }
  ]
}

When to import, I got a warning 'unknown type <drools:Import>', and elements were ignored, so what should I to do to define right data type for drools? Thank you!

What you are missing is the tagAlias hint in the drools package descriptor:

{
  "name": "DROOLS",
  "uri": "http://www.jboss.org/drools",
  "prefix": "drools",
  "xml": {
    "tagAlias": "lowerCase"
  },
  ...
}

That tells moddle-xml how to serialize types.

Next time you could provide a PR directly against the bpmn-moddle repository to speed up the look-inside process. See this commit for how I verified the correct loading / serialization for your drools extension.

Yes, It works. Strict and beautiful test cases. Thank you and your team, perfect work!