⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soap.tcl

📁 Linux下的MSN聊天程序源码
💻 TCL
📖 第 1 页 / 共 4 页
字号:
        array set fault [decomposeSoap $faultNode]        dom::DOMImplementation destroy $doc        if {![info exists fault(detail)]} { set fault(detail) {}}        return -code error -errorinfo $fault(detail) \            [list $fault(faultcode) $fault(faultstring)]    }    # If there is a header element then make it available via SOAP::getHeader    set headerNode [selectNode $doc "/Envelope/Header"]    if {$headerNode != {} \            && [string match \                    "http://schemas.xmlsoap.org/soap/envelope/" \                    [namespaceURI $headerNode]]} {        set procvar(headers) [decomposeSoap $headerNode]    } else {        set procvar(headers) {}    }        set result {}    if {[info exists procvar(name)]} {        set responseName "$procvar(name)Response"    } else {        set responseName "*"    }    set responseNode [selectNode $doc "/Envelope/Body/$responseName"]    if {$responseNode == {}} {        set responseNode [lindex [selectNode $doc "/Envelope/Body/*"] 0]    }    set nodes [getElements $responseNode]    foreach node $nodes {        set r [decomposeSoap $node]        if {$result == {}} { set result $r } else { lappend result $r }    }    dom::DOMImplementation destroy $doc    return $result}# -------------------------------------------------------------------------# Description:#   Parse an XML-RPC response payload. Check for fault response otherwise #   extract the value data.# Parameters:#   procVarName  - the name of the XML-RPC method configuration variable#   xml          - the XML payload of the response# Result:#   The extracted value(s). Array types are converted into lists and struct#   types are turned into lists of name/value pairs suitable for array set# Notes:#   The XML-RPC fault response doesn't allow us to add in extra values#   to the fault struct. So where to put the servers errorInfo?#proc ::SOAP::parse_xmlrpc_response { procVarName xml } {    upvar $procVarName procvar    set result {}    if {$xml == {} && ![string match "http*" $procvar(proxy)]} {        # This is probably not an error. SMTP and FTP won't return anything        # HTTP should always return though (I think).        return {}    } else {        if {[catch {set doc [dom::DOMImplementation parse $xml]}]} {            return -code error -errorcode Server \                "Server response is not well-formed XML.\n\                  response was $xml"        }    }    set faultNode [selectNode $doc "/methodResponse/fault"]    if {$faultNode != {}} {        array set err [lindex [decomposeXMLRPC \                [selectNode $doc /methodResponse]] 0]        dom::DOMImplementation destroy $doc        return -code error \            -errorcode $err(faultCode) \            -errorinfo $err(faultString) \            "Received XML-RPC Error"    }        # Recurse over each params/param/value    set n_params 0    foreach valueNode [selectNode $doc \            "/methodResponse/params/param/value"] {        lappend result [xmlrpc_value_from_node $valueNode]        incr n_params    }    dom::DOMImplementation destroy $doc    # If (as is usual) there is only one param, simplify things for the user    # ie: sort {one two three} should return a 3 element list, not a single    # element list whose first element has 3 elements!    if {$n_params == 1} {set result [lindex $result 0]}    return $result}# -------------------------------------------------------------------------# Description:#   Parse an XML-RPC call payload. Extracts method name and parameters.# Parameters:#   procVarName  - the name of the XML-RPC method configuration variable#   xml          - the XML payload of the response# Result:#   A list containing the name of the called method as first element#   and the extracted parameter(s) as second element. Array types are#   converted into lists and struct types are turned into lists of#   name/value pairs suitable for array set# Notes:#proc ::SOAP::parse_xmlrpc_request { xml } {    set result {}    if {[catch {set doc [dom::DOMImplementation parse $xml]}]} {        return -code error -errorinfo Server \            "Client request is not well-formed XML.\n\            call was $xml"    }    set methodNode [selectNode $doc "/methodCall/methodName"]    set methodName [getElementValue $methodNode]    # Get the parameters.    # If there is only one parameter, simplify things for the user,    # ie: sort {one two three} should return a 3 element list, not a    # single element list whose first element has 3 elements!    set paramsNode [selectNode $doc "/methodCall/params"]    set paramValues {}    if {$paramsNode != {}} {	set paramValues [decomposeXMLRPC $paramsNode]    }    if {[llength $paramValues] == 1} {        set paramValues [lindex $paramValues 0]    }    catch {dom::DOMImplementation destroy $doc}    return [list $methodName $paramValues]}# -------------------------------------------------------------------------### NB: this procedure needs to be moved into XMLRPC namespace# Description:#   Retrieve the value under the given <value> node.# Parameters:#   valueNode - reference to a <value> element in the response dom tree# Result:#   Either a single value or a list of values. Arrays expand into a list#   of values, structs to a list of name/value pairs.# Notes:#   Called recursively when processing arrays and structs.#proc ::SOAP::xmlrpc_value_from_node {valueNode} {    set value {}    set elts [getElements $valueNode]    if {[llength $elts] != 1} {        return [getElementValue $valueNode]    }    set typeElement [lindex $elts 0]    set type [dom::node cget $typeElement -nodeName]    if {$type == "array"} {        set dataElement [lindex [getElements $typeElement] 0]        foreach valueElement [getElements $dataElement] {            lappend value [xmlrpc_value_from_node $valueElement]        }    } elseif {$type == "struct"} {        # struct type has 1+ members which have a name and a value elt.        foreach memberElement [getElements $typeElement] {            set params [getElements $memberElement]            foreach param $params {                set nodeName [dom::node cget $param -nodeName]                if { $nodeName == "name"} {                    set pname [getElementValue $param]                } elseif { $nodeName == "value" } {                    set pvalue [xmlrpc_value_from_node $param]                }            }            lappend value $pname $pvalue        }    } else {        set value [getElementValue $typeElement]    }    return $value}# -------------------------------------------------------------------------proc ::SOAP::insert_headers {node headers} {    set doc [SOAP::Utils::getDocumentElement $node]    if {[set h [selectNode $doc /Envelope/Header]] == {}} {        set e [dom::document cget $doc -documentElement]        set h [dom::document createElement $e "SOAP-ENV:Header"]    }    foreach {name value} $headers {        if {$name != {}} {            set elt [dom::document createElement $h $name]            insert_value $elt $value        }    }}# -------------------------------------------------------------------------proc ::SOAP::insert_value {node value} {    set type     [rpctype $value]    set subtype  [rpcsubtype $value]    set attrs    [rpcattributes $value]    set headers  [rpcheaders $value]    set value    [rpcvalue $value]    set typeinfo [typedef -info $type]    set typexmlns [typedef -namespace $type]    # Handle any header elements    if {$headers != {}} {        insert_headers $node $headers    }        # If the rpcvar namespace is a URI then assign it a tag and ensure we    # have our colon only when required.    if {$typexmlns != {} && [regexp : $typexmlns]} {        dom::element setAttribute $node "xmlns:t" $typexmlns        set typexmlns t    }    if {$typexmlns != {}} { append typexmlns : }    # If there are any attributes assigned, apply them.    if {$attrs != {}} {        foreach {aname avalue} $attrs {            dom::element setAttribute $node $aname $avalue        }    }    if {[string match {*()} $typeinfo] || [string match {*()} $type]         || [string match array $type]} {        # array type: arrays are indicated by one or more () suffixes or        # the word 'array' (depreciated)        if {[string length $typeinfo] == 0} {            set dimensions [regexp -all -- {\(\)} $type]            set itemtype [string trimright $type ()]            if {$itemtype == "array"} {                set itemtype ur-type                set dimensions 1            }        } else {            set dimensions [regexp -all -- {\(\)} $typeinfo]            set itemtype [string trimright $typeinfo ()]        }                # Look up the typedef info of the item type        set itemxmlns [typedef -namespace $itemtype]        if {$itemxmlns != {} && [regexp : $itemxmlns]} {            dom::element setAttribute $node "xmlns:i" $itemxmlns            set itemxmlns i        }                # Currently we do not support non-0 offsets into the array.        # This is because I don;t know how I should present this to the        # user. It's got to be a dynamic attribute on the value.        dom::element setAttribute $node \                "xmlns:SOAP-ENC" "http://schemas.xmlsoap.org/soap/encoding/"        dom::element setAttribute $node "xsi:type" "SOAP-ENC:Array"        dom::element setAttribute $node "SOAP-ENC:offset" "\[0\]"        # we need to break a multi-dim array into r0c0,r0c1,r1c0,r1c1        # so list0 followed by list1 etc.        # FIX ME        set arrayType "$itemxmlns:$itemtype"        #for {set cn 0} {$cn < $dimensions} {incr cn}        append arrayType "\[[llength $value]\]"        dom::element setAttribute $node "SOAP-ENC:arrayType" $arrayType        foreach elt $value {            set d_elt [dom::document createElement $node "item"]            if {[string match "ur-type" $itemtype]} {                insert_value $d_elt $elt            } else {                insert_value $d_elt [rpcvar $itemtype $elt]            }        }    } elseif {[llength $typeinfo] > 1} {        # a typedef'd struct.        if {$typexmlns != {}} {            dom::element setAttribute $node "xsi:type" "${typexmlns}${type}"        }        array set ti $typeinfo        # Bounds checking - <simon@e-ppraisal.com>        if {[llength $typeinfo] != [llength $value]} {            return -code error "wrong # args:\                type $type contains \"$typeinfo\""        }        foreach {eltname eltvalue} $value {            set d_elt [dom::document createElement $node $eltname]            if {![info exists ti($eltname)]} {                return -code error "invalid member name:\                    \"$eltname\" is not a member of the $type type."            }            insert_value $d_elt [rpcvar $ti($eltname) $eltvalue]        }    } elseif {$type == "struct"} {        # an unspecified struct        foreach {eltname eltvalue} $value {            set d_elt [dom::document createElement $node $eltname]            insert_value $d_elt $eltvalue        }    } else {        # simple type or typedef'd enumeration        if {$typexmlns != {}} {            dom::element setAttribute $node "xsi:type" "${typexmlns}${type}"        }        dom::document createTextNode $node $value    }}# -------------------------------------------------------------------------package require SOAP::http;             # TclSOAP 1.6.2+package provide SOAP $::SOAP::version# -------------------------------------------------------------------------# Local variables:#    indent-tabs-mode: nil# End:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -