文章 sun yao · 一月 4, 2023 6m read

一、目的 因使用BP中Switch分支来区分不同节点(即接口)及流向,个人已知方法中无相关统计功能能直接获取各分支节点及流向BO(调用第三方系统)信息,且当前使用系统未封装相关模块供查询,故通过解析BP中XData的方式获取Switch-Case节点及Call调用相关信息

二、解析类中的XData数据

/// 解析类中的XData内容
/// SELECT * FROM %Dictionary.CompiledXData
/// xdataID XData表ID
/// d ##class(BOE.TEST.ClassAnalysis).XDataAnalysisTextReader("JHIP.SM.BP.View||BPL")
ClassMethod XDataAnalysisTextReader(xdataID As %String) As %Status
{
   //获取XData流
   s compiledXdata=##class(%Dictionary.CompiledXData).%OpenId(xdataID)
   s tStream=compiledXdata.Data
   If '$IsObject(tStream) s tSC=%objlasterror q
   
   //逐行读取xml
   s status=##class(%XML.TextReader).ParseStream(tStream,.textreader)
   if $$$ISERR(status) do $System.Status.DisplayError(status) q
   s conditionMsgCode="sy"
   while textreader.Read()
   {
	   //节点类型为element
       if (textreader.NodeType="element"){
	       //节点路径中包含/switch/case且case为结尾
	       if ((textreader.Path["/switch/case")&&(textreader.Path'["/switch/case/")){ //接口switch case解析接口 element
	       		//节点有属性
	       		if (textreader.HasAttributes){
		       		//移动到对应的属性节点Attribute
		       		if (textreader.MoveToAttributeName("condition")){
			       		s condition=textreader.Value
			       		s len=$l(condition,"||")
			       		for i=1:1:len{
				       		s tepCondition=$p(condition,"||",i)
				       		if (tepCondition["'="){
					       		s conditionMsgCode=$tr($p(tepCondition,"action",2),"""")
					       		if (conditionMsgCode=""){
						       		s conditionMsgCode=$tr($p(tepCondition,"OriginalDocId",2),"""")
					       		}
				       		}else{
				       			s conditionMsgCode=$tr($p(tepCondition,"=",2),"""")
				       		}
			       		}
			       		//b:conditionMsgCode=""
			       		s conditionMsgCode=$tr(conditionMsgCode,"()")
			       		if (conditionMsgCode=""){ //如果未定义分支条件,则设置为类名
				       		s conditionMsgCode=xdataID
			       		}
			       		//移动到下一个节点Node
			       		d textreader.Read()
			       		if (textreader.HasAttributes){
				       		if (textreader.MoveToAttributeName("name")){
					       		s name=textreader.Value
			       				s ^sy(conditionMsgCode)=name
				       		}
			       		}else{
				       		s ^sy(conditionMsgCode)=""
			       		}
		       		}
	       		}		
	       }
	       if ((textreader.Path["/switch/case/")&&(textreader.Path["/call")&&(textreader.Path'["/call/")){ //接口switch case call解析接口 element
	       		s callName="",callTarget=""
	       		if (textreader.HasAttributes){
		       		if (textreader.MoveToAttributeName("name")){
			       		s callName=textreader.Value
			       		s ^sy(conditionMsgCode,"callName",callName)=callName
		       		}
		       		if (textreader.MoveToAttributeName("target")){
			       		s callTarget=textreader.Value
			       		s ^sy(conditionMsgCode,"callTarget",callTarget)=callTarget
		       		}
	       		}		
	       }
       }
   }
}
0
0 282
文章 sun yao · 十月 12, 2022 10m read

概述

现有Ensemble平台BS(服务)、BP(流程)、BO(操作)需对平台及开发语言有一定的了解才能实现,为简化用户操作,现对现有平台进行二次封装,通过API接口的形式进行前后端分离,通过前端界面操作实现BS(对外提供的服务)、BP、BO(逻辑处理或调用外部的服务)自动生成(通过%Dictionary实现),具体实现如下。

一、开发技术和工具

版本:Ensemble 2017.2.1

二、涉及公用类

2.1 %Dictionary.ClassDefinition(自定义类)

• property Super as %CacheString; Specifies one or more superclasses for the class. 定义一个或多个父类,继承父类

• property** ProcedureBlock** as %Boolean [ InitialExpression = 0 ]; Specifies that the class uses procedure block for method code. 设置类是否允许使用程序块,程序块强制实施变量作用域:方法无法看到由其调用方定义的变量,程序块中的任何变量都会自动成为私有变量

• relationship Parameters as %Dictionary.

10
6 893
问题 sun yao · 七月 1, 2022

%XML.XPATH.Document中CreateFromFile方法,pSource入参传https开头的webService地址,解析报错错误 #6901: XSLT XML转换器错误: unsupported protocol in URL in at line 0 offset 0

如: zw ##class(%XML.XPATH.Document).CreateFromFile("https://localhost/services/MessageNotify?wsdl",.tDoc,,,,,"http://schemas.xmlsoap.org/wsdl/")

1
0 189