ActivitiカスタムBPMNタグレポート:org.xml.sax.SAXParseException:要素userTaskが名前空間http://activiti.org/bpmnにバインドされました

プロジェクトアドレス:activiti-ワークフロー

CCのタグをユーザーノード拡張子に追加すると、org.xml.sax.SAXParseExceptionがbpmnファイルインポートプロセスを通じて報告されます。要素「userTask」が名前空間「http:// activiti」にバインドされるように指定されています。 .org / bpmn "属性" XXXX。 "

bebuggerfを通じて、特定のエラーがXMLNSDocumentScannerImplクラスに表示されることが判明しました

 if (length > 1) {
    
    
 		//对元素进行校验name不为空说明有重复元素
	   QName name = fAttributes.checkDuplicatesNS();
       if (name != null) {
    
    
           if (name.uri != null) {
    
    
               fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
                       "AttributeNSNotUnique",
                       new Object[]{
    
    fElementQName.rawname, name.localpart, name.uri},
                       XMLErrorReporter.SEVERITY_FATAL_ERROR);
           } else {
    
    
               fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
                       "AttributeNotUnique",
                       new Object[]{
    
    fElementQName.rawname, name.rawname},
                       XMLErrorReporter.SEVERITY_FATAL_ERROR);
           }
       }
   }

checkDuplicatesNSメソッドを見てください

    public QName checkDuplicatesNS() {
    
    
        // If the list is small check for duplicates using pairwise comparison.
        final int length = fLength;
        if (length <= SIZE_LIMIT) {
    
    
            final Attribute[] attributes = fAttributes;
            for (int i = 0; i < length - 1; ++i) {
    
    
                Attribute att1 = attributes[i];
                for (int j = i + 1; j < length; ++j) {
    
    
                    Attribute att2 = attributes[j];
                    //只有当标签名称和命名空间一样时有返回
                    if (att1.name.localpart == att2.name.localpart &&
                        att1.name.uri == att2.name.uri) {
    
    
                        return att2.name;
                    }
                }
            }
            return null;
        }
        // If the list is large check duplicates using a hash table.
        else {
    
    
            return checkManyDuplicatesNS();
        }
    }

間違ったオブジェクト情報を投稿する
ここに画像の説明を挿入
同じタグが2つ存在しないと言っても過言ではありませんが、設定を繰り返すことはできますか?コードを注意深く確認したところ、重複する設定は見つかりませんでした。
独自の拡張機能のコード。CustomUserTaskXMLConverterで設定されたこの属性のみ

@Override
  @SuppressWarnings("unchecked")
  protected void writeAdditionalAttributes(BaseElement element, BpmnModel model, XMLStreamWriter xtw) throws Exception {
    
    
	//省略部分代码
    //设置抄送标签属性
    writeQualifiedAttribute(ATTRIBUTE_TASK_USER_CANDIDATE_NOTIFY_USERS, convertToDelimitedString(userTask.getCandidateNotifyUsers()), xtw);
   	//省略部分代码
    // 注意,注意,注意
    BpmnXMLUtil.writeCustomAttributes(userTask.getAttributes().values(), xtw, defaultElementAttributes,
        defaultActivityAttributes, defaultUserTaskAttributes);
  }

この時点で、activitiのソースコードが別の属性を設定していると結論付けることができます。Activitiは、BaseBpmnXMLConverter#convertToXMLからbpmnファイルを解析します。

public void convertToXML(XMLStreamWriter xtw, BaseElement baseElement, BpmnModel model) throws Exception {
    
    
    xtw.writeStartElement(getXMLElementName());
    boolean didWriteExtensionStartElement = false;
    writeDefaultAttribute(ATTRIBUTE_ID, baseElement.getId(), xtw);
    if (baseElement instanceof FlowElement) {
    
    
      writeDefaultAttribute(ATTRIBUTE_NAME, ((FlowElement) baseElement).getName(), xtw);
    }
    
    if (baseElement instanceof FlowNode) {
    
    
      final FlowNode flowNode = (FlowNode) baseElement;
      if (flowNode.isAsynchronous()) {
    
    
        writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_ASYNCHRONOUS, ATTRIBUTE_VALUE_TRUE, xtw);
        if (flowNode.isNotExclusive()) {
    
    
          writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_EXCLUSIVE, ATTRIBUTE_VALUE_FALSE, xtw);
        }
      }
      
      if (baseElement instanceof Activity) {
    
    
        final Activity activity = (Activity) baseElement;
        if (activity.isForCompensation()) {
    
    
          writeDefaultAttribute(ATTRIBUTE_ACTIVITY_ISFORCOMPENSATION, ATTRIBUTE_VALUE_TRUE, xtw);
        }
        if (StringUtils.isNotEmpty(activity.getDefaultFlow())) {
    
    
          FlowElement defaultFlowElement = model.getFlowElement(activity.getDefaultFlow());
          if (defaultFlowElement instanceof SequenceFlow) {
    
    
            writeDefaultAttribute(ATTRIBUTE_DEFAULT, activity.getDefaultFlow(), xtw);
          }
        }
      }
      
      if (baseElement instanceof Gateway) {
    
    
        final Gateway gateway = (Gateway) baseElement;
        if (StringUtils.isNotEmpty(gateway.getDefaultFlow())) {
    
    
          FlowElement defaultFlowElement = model.getFlowElement(gateway.getDefaultFlow());
          if (defaultFlowElement instanceof SequenceFlow) {
    
    
            writeDefaultAttribute(ATTRIBUTE_DEFAULT, gateway.getDefaultFlow(), xtw);
          }
        }
      }
    }
	//具体子类执行
    writeAdditionalAttributes(baseElement, model, xtw);

    if (baseElement instanceof FlowElement) {
    
    
      final FlowElement flowElement = (FlowElement) baseElement;
      if (StringUtils.isNotEmpty(flowElement.getDocumentation())) {
    
    

        xtw.writeStartElement(ELEMENT_DOCUMENTATION);
        xtw.writeCharacters(flowElement.getDocumentation());
        xtw.writeEndElement();
      }
    }

    didWriteExtensionStartElement = writeExtensionChildElements(baseElement, didWriteExtensionStartElement, xtw);
    didWriteExtensionStartElement = writeListeners(baseElement, didWriteExtensionStartElement, xtw);
    didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(baseElement, didWriteExtensionStartElement, model.getNamespaces(), xtw);
    if (baseElement instanceof Activity) {
    
    
      final Activity activity = (Activity) baseElement;
      FailedJobRetryCountExport.writeFailedJobRetryCount(activity, xtw);

    }

    if (didWriteExtensionStartElement) {
    
    
      xtw.writeEndElement();
    }

    if (baseElement instanceof Activity) {
    
    
      final Activity activity = (Activity) baseElement;
      MultiInstanceExport.writeMultiInstance(activity, xtw);

    }

    writeAdditionalChildElements(baseElement, model, xtw);

    xtw.writeEndElement();
  }

このメソッドには設定コードが見つかりませんでした。サブカテゴリのみが表示されます。上記のCustomUserTaskXMLConverterのwriteAdditionalAttributesメソッドに注意してください

 BpmnXMLUtil.writeCustomAttributes(userTask.getAttributes().values(), xtw, defaultElementAttributes,
        defaultActivityAttributes, defaultUserTaskAttributes);

userTaskの属性属性はここでは設定されていません。空である必要がありますが、フォローアップしたところ、そうではなく、たまたまCCの属性であることがわかりました。ここであなたは理解するでしょう、別の設定がここにあります。
ここに画像の説明を挿入

この時点で、属性がいつ設定されるかを決定するだけで済みます。BaseElement#addAttributeにブレークポイント設定します。最後に、それがCustomUserTaskXMLConverter#convertXMLToElementメソッドであることがわかりました

@Override
  protected BaseElement convertXMLToElement(XMLStreamReader xtr, BpmnModel model) throws Exception {
    
    
   	//省略部分代码
   	//设置Attributes属性
    BpmnXMLUtil.addCustomAttributes(xtr, userTask, defaultElementAttributes,
        defaultActivityAttributes, defaultUserTaskAttributes);

    parseChildElements(getXMLElementName(), userTask, childParserMap, model, xtr);
    
    return userTask;
  }

BpmnXMLUtil.addCustomAttributesメソッド、主にisBlacklisted

public static void addCustomAttributes(XMLStreamReader xtr, BaseElement element, List<ExtensionAttribute>... blackLists) {
    
    
	//迭代出各个属性判断是否有命名空间,是否是自定义属性
    for (int i = 0; i < xtr.getAttributeCount(); i++) {
    
    
      ExtensionAttribute extensionAttribute = new ExtensionAttribute();
      extensionAttribute.setName(xtr.getAttributeLocalName(i));
      extensionAttribute.setValue(xtr.getAttributeValue(i));
      if (StringUtils.isNotEmpty(xtr.getAttributeNamespace(i))) {
    
    
        extensionAttribute.setNamespace(xtr.getAttributeNamespace(i));
      }
      if (StringUtils.isNotEmpty(xtr.getAttributePrefix(i))) {
    
    
        extensionAttribute.setNamespacePrefix(xtr.getAttributePrefix(i));
      }
      if (!isBlacklisted(extensionAttribute, blackLists)) {
    
    
        element.addAttribute(extensionAttribute);
      }
    }
  }

何を見てみましょうisBlacklistedはありませんが

 public static boolean isBlacklisted(ExtensionAttribute attribute, List<ExtensionAttribute>... blackLists) {
    
    
    if (blackLists != null) {
    
    
      for (List<ExtensionAttribute> blackList : blackLists) {
    
    
        for (ExtensionAttribute blackAttribute : blackList) {
    
    
        	//是否是默认属性
          if (blackAttribute.getName().equals(attribute.getName())) {
    
    
          //命名空间是否一样
            if (blackAttribute.getNamespace() != null && attribute.getNamespace() != null && blackAttribute.getNamespace().equals(attribute.getNamespace()))
              return true;
            if (blackAttribute.getNamespace() == null && attribute.getNamespace() == null)
              return true;
          }
        }
      }
    }
    return false;
  }

ブラックリスト値

 /**
   * 用户节点默认通用属性
   */
  protected static final List<ExtensionAttribute> defaultUserTaskAttributes = Arrays.asList(
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_FORM_FORMKEY),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_DUEDATE),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_BUSINESS_CALENDAR_NAME),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_ASSIGNEE),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_OWNER),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_PRIORITY),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATEUSERS),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATEGROUPS),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CATEGORY),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_EXTENSIONID),
          //设置抄送为默认通用标签
          //new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATE_NOTIFY_USERS),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_SKIP_EXPRESSION)
  );

ここで設定した後、すべてOKをテストします。

おすすめ

転載: blog.csdn.net/qq_34758074/article/details/106356127