import web.msxml; import inet.http; namespace web; class soapClient{ ctor( url,username,password){ this.http = ..inet.http(); this.http.username = username; this.http.password = password; var wsdl = ..web.msxml( ..string.indexOf(url,"?") ? url : url + "?wsdl" ); if(#wsdl.document.parseError.reason) return null,wsdl.document.parseError.reason; this.wsdl = wsdl; this.soapUrl = url; this.bindService = function(serviceName){ import console; var service; if(serviceName){ service = this.wsdl.queryNodes( name = "^" + serviceName + "";tagName = "^wsdl\:service$"); } else { service = this.wsdl.documentElement.getElementsByTagName("wsdl:service"); service = service.length ? service(0) : null; } if(!service){ error("打开SOAP服务失败",2); } this.soapServiceName = service.getAttributeNode("name").nodeValue; var soapAddress = service.getElementsByTagName("soap:address"); if(soapAddress.length) { this.soapUrl = soapAddress(0).getAttributeNode("location").nodeValue; this.soapPortName = soapAddress(0).parentNode.getAttributeNode("name").nodeValue; } if( !(this.soapUrl && this.soapPortName) ){ error("获取SOAP接口地址失败",2); } var bindings = wsdl.documentElement.getElementsByTagName("wsdl:binding"); if( bindings.length ){ for(i=1;bindings.length;1){ if(bindings(i-1).getAttributeNode("name").nodeValue==this.soapPortName){ this.soapPortNode = bindings(i-1); this.soapOperations = this.soapPortNode.getElementsByTagName("wsdl:operation"); break; } } } if(!this.soapPortNode){ error("打开SOAP服务接口失败",2); } } this.soapTargetNamespace = wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue; this.bindService(); }; _invoke = function(method,param,resultType,resultComplexType){ var sr = /* */ sr = sr + "<" + method + " xmlns=""" + this.soapTargetNamespace + """>" + param.toXml() + " "; var soapaction = this.soapTargetNamespace; if( soapaction ? ( ! ..string.endsWith(soapaction,"/") ) ) soapaction += "/"; soapaction += method; if(this.soapOperations){ for(i=1;this.soapOperations.length;1){ var op = this.soapOperations(i-1); if(op.attributes.getNamedItem("name").nodeValue==method){ var sop = op.getElementsByTagName("soap:operation") if(sop.length){ soapaction = sop(0).attributes.getNamedItem("soapAction").nodeValue; } } } } var ret,err = this.http.post(this.soapUrl,sr, "SOAPAction:" + soapaction + '\r\nContent-Type:text/xml; charset=utf-8\r\n'); if(!ret) return null,err; ret = ..web.msxml( ret ); var nd = ret.documentElement.getElementsByTagName(method + "Result") if(nd.length == 0) nd = ret.documentElement.getElementsByTagName(method + "return") if(nd.length == 0){ if(ret.faultcode.length > 0 ) error(ret.faultstring(0).childNodes(0).nodeValue,2) } else { this.lastResultXml = nd(0); return _wsdlParseObject(nd(0) ,resultType,resultComplexType) } } @_meta; } import web.soapClient.parameters; namespace soapClient{ _wsdlGetComplexType = function(wsdl,method){ var methodWsdl = wsdl.queryNodes( name = "^" + method + "$";tagName = "!\welement$") if(!#methodWsdl) return; var ns = ..string.match( methodWsdl[1].tagName,"\a+\:") var complexType = methodWsdl[1].getElementsByTagName( ..string.concat( ns,"complexType") ); if( complexType.length ) { var sequence = complexType(0).getElementsByTagName( ..string.concat( ns,"sequence") ); if( sequence.length && sequence(0).hasChildNodes() ) { return sequence(0).childNodes ; } } } _meta = { _get = function( method ){ var argsWsdl = _wsdlGetComplexType(owner.wsdl,method) var resultType; var resultComplexType; { var resultWsdl = owner.wsdl.queryNodes( name = "^" + method + "Result$";tagName = "!\welement$";type="\a+"); var resultComplexWsdl; if( #resultWsdl ){ resultType = ..string.match( resultWsdl[1].getAttributeNode("type").nodeValue,"!\w\a+$"); } else{ resultComplexWsdl = _wsdlGetComplexType(owner.wsdl,method + "Result") } } owner[[method]] = function(...){ var param = parameters(); if( argsWsdl ){ var args = { ... }; for(i=1;#args;1){ param.add( argsWsdl(i-1).attributes.getNamedItem("name").nodeValue,args[i]) } } return owner._invoke(method,param,resultType,resultComplexType); } return owner[[method]]; } }; _wsdlParseObject = function(node,resultType,resultComplexType ) { if(!node) return; if(node.nodeType == 3/*TEXT*/ || node.nodeType == 4/*CDATA*/){ var value = node.nodeValue; select( resultType ) { case "string" return (value != null) ? value : ""; case "boolean" return value == "true"; case "int","long" return (value != null) ? tonumber(value) : 0; case "double" return (value != null) ? tonumber(value) : 0; case "datetime"{ if( value ){ return ..time(value,"%Y-%m-%dT%H:%M:%S"); } } else { return value; } } } return _wsdlParseComplexObject(node,resultType,resultComplexType ) } _wsdlParseComplexObject = function(node,resultType,resultComplexType ) { if(!node) return; if (node.childNodes.length == 1){ var node = node.childNodes(0); if(node.nodeType == 3 || node.nodeType == 4 ) return _wsdlParseObject(node, resultType,resultComplexType); } var isarray = resultType ? ..string.find( ..string.lower( resultType ) , "arrayof") ; if(!isarray) { var obj = null; if(node.hasChildNodes()) { obj = {}; for index,child in ..com.each( node.childNodes ) { obj[child.nodeName] = _wsdlParseObject(child,resultType,resultComplexType);; } } return obj; } else { var obj = null; if(node.hasChildNodes()) { obj = {}; for(i=0;node.childNodes.length-1){ ..table.push(obj,_wsdlParseObject(node.childNodes(i), resultType,resultComplexType ) ) } } return obj; } } } /**intellisense() web.soapClient = SOAP客户端支持库 web.soapClient(.(WebService网址,用户名,密码) = 创建SOAP客户端,\n必须指定有效WSDL网址,\n用户名与密码为可选参数 web.soapClient() = !web_soapClient. !web_soapClient.接口函数名字(调用参数) = !web_soapClient.lastResultXml = 调用接口最后一次返回值创建XML节点对象\n!xnode. !web_soapClient.http = 用于发送请求的http客户端\n!inet_http. !web_soapClient.bindService(__) = 绑定服务,参数指定服务名,无参数绑定默认服务\n在创建对象时此函数会被自动调用一次并绑定默认服务 !web_soapClient.soapUrl = 发送SOAP请求的目标URL,默认自WSDL中自动获取 !web_soapClient.soapPortName = 当前绑定接口名 !web_soapClient.soapServiceName = 当前绑定服务名 !web_soapClient.soapTargetNamespace = SOAP目标命名空间 end intellisense**/