function SOAPClientParameters()
{
var _pl = new Array();
this.add = function(name, value) 
{
_pl[name] = value; 
return this; 
}
this.toXml = function()
{
var xml = "";
for(var p in _pl)
{
switch(typeof(_pl[p])) 
{
                case "string":
                case "number":
                case "boolean":
                case "object":
                    xml += "<" + p + ">" + SOAPClientParameters._serialize(_pl[p]) + "</" + p + ">";
                    break;
                default:
                    break;
            }
}
return xml;
}
}
SOAPClientParameters._serialize = function(o)
{
    var s = "";
    switch(typeof(o))
    {
        case "string":
            s += o.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); break;
        case "number":
        case "boolean":
            s += o.toString(); break;
        case "object":
            // Date
            if(o.constructor.toString().indexOf("function Date()") > -1)
            {
        
                var year = o.getFullYear().toString();
                var month = (o.getMonth() + 1).toString(); month = (month.length == 1) ? "0" + month : month;
                var date = o.getDate().toString(); date = (date.length == 1) ? "0" + date : date;
                var hours = o.getHours().toString(); hours = (hours.length == 1) ? "0" + hours : hours;
                var minutes = o.getMinutes().toString(); minutes = (minutes.length == 1) ? "0" + minutes : minutes;
                var seconds = o.getSeconds().toString(); seconds = (seconds.length == 1) ? "0" + seconds : seconds;
                var milliseconds = o.getMilliseconds().toString();
                var tzminutes = Math.abs(o.getTimezoneOffset());
                var tzhours = 0;
                while(tzminutes >= 60)
                {
                    tzhours++;
                    tzminutes -= 60;
                }
                tzminutes = (tzminutes.toString().length == 1) ? "0" + tzminutes.toString() : tzminutes.toString();
                tzhours = (tzhours.toString().length == 1) ? "0" + tzhours.toString() : tzhours.toString();
                var timezone = ((o.getTimezoneOffset() < 0) ? "+" : "-") + tzhours + ":" + tzminutes;
                s += year + "-" + month + "-" + date + "T" + hours + ":" + minutes + ":" + seconds + "." + milliseconds + timezone;
            }
            // Array
            else if(o.constructor.toString().indexOf("function Array()") > -1)
            {
                for(var p in o)
                {
                    if(!isNaN(p))   // linear array
                    {
                        (/function\s+(\w*)\s*\(/ig).exec(o[p].constructor.toString());
                        var type = RegExp.$1;
                        switch(type)
                        {
                            case "":
                                type = typeof(o[p]);
                            case "String":
                                type = "string"; break;
                            case "Number":
                                type = "int"; break;
                            case "Boolean":
                                type = "bool"; break;
                            case "Date":
                                type = "DateTime"; break;
                        }
                        s += "<" + type + ">" + SOAPClientParameters._serialize(o[p]) + "</" + type + ">"
                    }
                    else    // associative array
                        s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">"
                }
            }
            // Object or custom function
            else
                for(var p in o)
                    s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">";
            break;
        default:
            break; // throw new Error(500, "SOAPClientParameters: type '" + typeof(o) + "' is not supported");
    }
    return s;
}function SOAPClient() {}SOAPClient.username = null;
SOAPClient.password = null;SOAPClient.invoke = function(url, method, parameters, async, callback)
{
if(async)
SOAPClient._loadWsdl(url, method, parameters, async, callback);
else
return SOAPClient._loadWsdl(url, method, parameters, async, callback);
}// private: wsdl cache
SOAPClient_cacheWsdl = new Array();// private: invoke async
SOAPClient._loadWsdl = function(url, method, parameters, async, callback)
{
// load from cache?
var wsdl = SOAPClient_cacheWsdl[url];
if(wsdl + "" != "" && wsdl + "" != "undefined")
return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl);
// get wsdl
var xmlHttp = SOAPClient._getXmlHttp();
xmlHttp.open("GET", url + "?wsdl", async);
if(async) 
{
xmlHttp.onreadystatechange = function() 
{
if(xmlHttp.readyState == 4)
SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp);
}
}
xmlHttp.send(null);
if (!async)
return SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp);
}
SOAPClient._onLoadWsdl = function(url, method, parameters, async, callback, req)
{
var wsdl = req.responseXML;
SOAPClient_cacheWsdl[url] = wsdl; // save a copy in cache
return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl);
}
SOAPClient._sendSoapRequest = function(url, method, parameters, async, callback, wsdl)
{
// get namespace
var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value;
// build SOAP request
var sr = 
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope " +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<soap:Body>" +
"<" + method + " xmlns=\"" + ns + "\">" +
parameters.toXml() +
"</" + method + "></soap:Body></soap:Envelope>";
// send request
var xmlHttp = SOAPClient._getXmlHttp();
if (SOAPClient.userName && SOAPClient.password){
xmlHttp.open("POST", url, async, SOAPClient.userName, SOAPClient.password);
// Some WS implementations (i.e. BEA WebLogic Server 10.0 JAX-WS) don't support Challenge/Response HTTP BASIC, so we send authorization headers in the first request
xmlHttp.setRequestHeader("Authorization", "Basic " + SOAPClient._toBase64(SOAPClient.userName + ":" + SOAPClient.password));
}
else
xmlHttp.open("POST", url, async);
var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + method;
xmlHttp.setRequestHeader("SOAPAction", soapaction);
xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
if(async) 
{
xmlHttp.onreadystatechange = function() 
{
if(xmlHttp.readyState == 4)
SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp);
}
}
xmlHttp.send(sr);
if (!async)
return SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp);
}SOAPClient._onSendSoapRequest = function(method, async, callback, wsdl, req) 
{
var o = null;
var nd = SOAPClient._getElementsByTagName(req.responseXML, method + "Result");
if(nd.length == 0)
nd = SOAPClient._getElementsByTagName(req.responseXML, "return"); // PHP web Service?
if(nd.length == 0)
{
if(req.responseXML.getElementsByTagName("faultcode").length > 0)
{
    if(async || callback)
        o = new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
else
    throw new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
}
}
else
o = SOAPClient._soapresult2object(nd[0], wsdl);
if(callback)
callback(o, req.responseXML);
if(!async)
return o;
}

解决方案 »

  1.   

    SOAPClient._soapresult2object = function(node, wsdl)
    {
        var wsdlTypes = SOAPClient._getTypesFromWsdl(wsdl);
        return SOAPClient._node2object(node, wsdlTypes);
    }
    SOAPClient._node2object = function(node, wsdlTypes)
    {
    // null node
    if(node == null)
    return null;
    // text node
    if(node.nodeType == 3 || node.nodeType == 4)
    return SOAPClient._extractValue(node, wsdlTypes);
    // leaf node
    if (node.childNodes.length == 1 && (node.childNodes[0].nodeType == 3 || node.childNodes[0].nodeType == 4))
    return SOAPClient._node2object(node.childNodes[0], wsdlTypes);
    //var isarray = SOAPClient._getTypeFromWsdl(node.nodeName, wsdlTypes).toLowerCase().indexOf("arrayof") != -1;
    var t = node.nodeName === 'return' // some array types are returned in <return> element...
    ? node.getAttribute('type') // ...with type in its attribute
    : SOAPClient._getTypeFromWsdl(node.nodeName, wsdlTypes);
    if (!t) t = node.getAttribute('xsi:type'); // if a browser doesn't understand namespaces
    var isarray = t.toLowerCase().indexOf("arrayof") != -1; // object node
    // object node
    if(!isarray)
    {
    var obj = null;
    if(node.hasChildNodes())
    obj = new Object();
    for(var i = 0; i < node.childNodes.length; i++)
    {
    var p = SOAPClient._node2object(node.childNodes[i], wsdlTypes);
    obj[node.childNodes[i].nodeName] = p;
    }
    return obj;
    }
    // list node
    else
    {
    // create node ref
    var l = new Array();
    for(var i = 0; i < node.childNodes.length; i++)
    l[l.length] = SOAPClient._node2object(node.childNodes[i], wsdlTypes);
    return l;
    }
    return null;
    }
    SOAPClient._extractValue = function(node, wsdlTypes)
    {
    var value = node.nodeValue;
    switch(SOAPClient._getTypeFromWsdl(node.parentNode.nodeName, wsdlTypes).toLowerCase())
    {
    default:
    case "s:string":
    return (value != null) ? value + "" : "";
    case "s:boolean":
    return value + "" == "true";
    case "s:int":
    case "s:long":
    return (value != null) ? parseInt(value + "", 10) : 0;
    case "s:double":
    return (value != null) ? parseFloat(value + "") : 0;
    case "s:datetime":
    if(value == null)
    return null;
    else
    {
    value = value + "";
    value = value.substring(0, (value.lastIndexOf(".") == -1 ? value.length : value.lastIndexOf(".")));
    value = value.replace(/T/gi," ");
    value = value.replace(/-/gi,"/");
    var d = new Date();
    d.setTime(Date.parse(value));
    return d;
    }
    }
    }
    SOAPClient._getTypesFromWsdl = function(wsdl)
    {
    var wsdlTypes = new Array();
    // IE
    var ell = wsdl.getElementsByTagName("s:element");
    var useNamedItem = true;
    // MOZ
    if(ell.length == 0)
    {
    ell = wsdl.getElementsByTagName("element");      
    useNamedItem = false;
    }
    for(var i = 0; i < ell.length; i++)
    {
    if(useNamedItem)
    {
    if(ell[i].attributes.getNamedItem("name") != null && ell[i].attributes.getNamedItem("type") != null) 
    wsdlTypes[ell[i].attributes.getNamedItem("name").nodeValue] = ell[i].attributes.getNamedItem("type").nodeValue;
    }
    else
    {
    if(ell[i].attributes["name"] != null && ell[i].attributes["type"] != null)
    wsdlTypes[ell[i].attributes["name"].value] = ell[i].attributes["type"].value;
    }
    }
    return wsdlTypes;
    }
    SOAPClient._getTypeFromWsdl = function(elementname, wsdlTypes)
    {
        var type = wsdlTypes[elementname] + "";
        return (type == "undefined") ? "" : type;
    }
    // private: utils
    SOAPClient._getElementsByTagName = function(document, tagName)
    {
    try
    {
    // trying to get node omitting any namespaces (latest versions of MSXML.XMLDocument)
    return document.selectNodes(".//*[local-name()=\""+ tagName +"\"]");
    }
    catch (ex) {}
    // old XML parser support
    return document.getElementsByTagName(tagName);
    }
    // private: xmlhttp factory
    SOAPClient._getXmlHttp = function() 
    {
    try
    {
    if(window.XMLHttpRequest) 
    {
    var req = new XMLHttpRequest();
    // some versions of Moz do not support the readyState property and the onreadystate event so we patch it!
    if(req.readyState == null) 
    {
    req.readyState = 1;
    req.addEventListener("load", 
    function() 
    {
    req.readyState = 4;
    if(typeof req.onreadystatechange == "function")
    req.onreadystatechange();
    },
    false);
    }
    return req;
    }
    if(window.ActiveXObject) 
    return new ActiveXObject(SOAPClient._getXmlHttpProgID());
    }
    catch (ex) {}
    throw new Error("Your browser does not support XmlHttp objects");
    }
    SOAPClient._getXmlHttpProgID = function()
    {
    if(SOAPClient._getXmlHttpProgID.progid)
    return SOAPClient._getXmlHttpProgID.progid;
    var progids = ["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
    var o;
    for(var i = 0; i < progids.length; i++)
    {
    try
    {
    o = new ActiveXObject(progids[i]);
    return SOAPClient._getXmlHttpProgID.progid = progids[i];
    }
    catch (ex) {};
    }
    throw new Error("Could not find an installed XML parser");
    }SOAPClient._toBase64 = function(input)
    {
    var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0; do {
    chr1 = input.charCodeAt(i++);
    chr2 = input.charCodeAt(i++);
    chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2;
    enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
    enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
    enc4 = chr3 & 63; if (isNaN(chr2)) {
    enc3 = enc4 = 64;
    } else if (isNaN(chr3)) {
    enc4 = 64;
    } output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
    keyStr.charAt(enc3) + keyStr.charAt(enc4);
    } while (i < input.length); return output;
    }
    <html>
    <head>
    <script language="javascript" type="text/javascript" src="http://192.168.137.222/iepg/soapclient.js"></script>
    <script type="text/javascript" language="javascript">
    function HelloWorld()
    {
        var pl = new SOAPClientParameters();
    pl.add("channel_id","4271188");
    pl.add("begin_time","2012-03-07 08:00:00");
    pl.add("end_time","2012-03-07 20:00:00");
    pl.add("desc_len","1");
        SOAPClient.invoke("http://192.168.137.222/iepg/ws.php", "epglist", pl, true, HelloWorld_callBack);
    }
    function HelloWorld_callBack(r)
    {
    alert(r.item.name);
    alert(r.item.startTime);
    alert(r.item.endTime);
    }
    </script>
    </head>
    <body>
    <form>
    <input  type="button" name="sad" value="按钮" onClick="HelloWorld()">
    </form>
    </body>
    </html>
    public function epglist($channel_id,$begin_time,$end_time,$desc_len){
    $datas= array();
    $ret=_epglist($channel_id,$begin_time,$end_time,$desc_len);
    foreach($ret as $item){
    $dn=new ChannelProgram();
    $dn->name=$item['prg_name'];
    $dn->startTime=$item['prg_startTime'];
    $dn->endTime=$item['prg_endTime'];
    $dn->desc=$item['prg_short_desc'];
    $dn->programid=$item['prg_id'];
    $datas[]= $dn;
    }
    return $datas;
    }
    请问各位大虾们,在使用SOAP调用webservice的时候.为什么外部的方法返回时对象或者字符串,便没有任何问题,可以很正常的执行下来,如果是数组或集合,它返回的将是数组中最后一组的属性.