Search code examples
xmlxpathvbscriptnamespacesmsxml

VBScript, MSXML and Namespaces


Given the following XML:

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <GetMsisdnResponse xmlns="http://my.domain.com/">
            <GetMsisdnResult>
                <RedirectUrl>http://my.domain.com/cw/DoIdentification.do2?sessionid=71de6551fc13e6625194</RedirectUrl>
            </GetMsisdnResult>
        </GetMsisdnResponse>
    </soap:Body>
</soap:Envelope>

I am trying to access the RedirectUrl element using XPath in VBScript:

set xml = CreateObject("MSXML2.DOMDocument")
xml.async = false
xml.validateOnParse = false
xml.resolveExternals = false
xml.setProperty "SelectionLanguage", "XPath"
xml.setProperty "SelectionNamespaces", "xmlns:s='http://my.domain.com/' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"

err.clear
on error resume next
xml.loadXML (xmlhttp.responseText)
if (err.number = 0) then

    redirectUrl = xml.selectSingleNode("/soap:Envelope/soap:Body/s:GetMsisdnResponse/s:GetMsisdnResult/s:RedirectUrl").text
end if

but it is failing to find the RedirectUrl node, therefore is nothing when I try to get the .text property. What am I doing wrong


Solution

  • You are using the wrong namespace declaration.

    In your XML you have

    http://www.w3.org/2003/05/soap-envelope

    but in your Script, you use

    http://schemas.xmlsoap.org/soap/envelope/

    This works for me:

    xml.setProperty "SelectionNamespaces", "xmlns:s='http://my.domain.com/' xmlns:soap='http://www.w3.org/2003/05/soap-envelope'"
    
    ' ...
    
    Set redirectUrl = xml.selectSingleNode("/soap:Envelope/soap:Body/s:GetMsisdnResponse/s:GetMsisdnResult/s:RedirectUrl")
    

    On a different note - I'd try to keep the lines that are affected by an On Error Resume Next statement at an absolute minimum. Ideally, it is in effect for a single critical line only (or you wrap the critical section in a Sub). This makes debugging a lot easier.

    For example, you are missing a Set statement in Set redirectUrl = .... This will fail silently when On Error Resume Next is on.

    Try

    ' this is better than loadXML(xmlHttp.responseText)
    xmlDocument.load(xmlHttp.responseStream)
    
    If (xmlDocument.parseError.errorCode <> 0) Then
      ' react to the parsing error
    End If
    
    Xpath = "/soap:Envelope/soap:Body/s:GetMsisdnResponse/s:GetMsisdnResult/s:RedirectUrl"
    Set redirectUrl = xml.selectSingleNode(Xpath)
    
    If redirectUrl Is Nothing Then
      ' nothing found
    Else
      ' do something
    End If
    

    See - no On Error Resume Next necessary.