代码之家  ›  专栏  ›  技术社区  ›  Mark Bell

如何在经典ASP(MSXML)中从该XML获取XML节点?

  •  1
  • Mark Bell  · 技术社区  · 15 年前

    好吧,我已经不知所措了。这似乎是一件微不足道的事情,但一个小时后,我仍然无法让它工作。

    我正试着从地图上获取时区列表 Campaign Monitor API ; 不幸的是,我需要使用的页面是用经典的ASP/Javascript编写的,所以我不能只使用API包装器。

    var request = Server.CreateObject("Msxml2.ServerXMLHTTP");
    
    request.open("GET", apiurl + "/User.GetTimezones?ApiKey=" + apikey, false);
    request.send();
    

    正确的XML将从服务器返回,如下所示:

    <anyType d1p1:type="ArrayOfString" xmlns:d1p1="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://api.createsend.com/api/"> 
        <string>(GMT) Casablanca</string> 
        <string>(GMT) Coordinated Universal Time</string> 
        <string>(GMT) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London</string> 
        <string>(GMT) Monrovia, Reykjavik</string> 
        <string>(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna</string> 
        <string>(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague</string> 
        <string>(GMT+01:00) Brussels, Copenhagen, Madrid, Paris</string> 
        (...and so on - I've truncated for the purpose of this question)
    </anyType>
    

    然后我将此XML加载到MSXML文档中:

    var response = Server.CreateObject("Msxml2.DOMDocument.4.0");
    response.async = false;
    response.validateOnParse = false;
    response.resolveExternals = false;
    
    response.setProperty("SelectionNamespaces", "xmlns:d1p1='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://api.createsend.com/api/'");
    response.setProperty("SelectionLanguage", "XPath");
    
    if (response.load(request.responseXML)) 
    {
        // If I uncomment this, the XML is correctly written out
        // Response.Write(response.xml);
    
        var nodes = response.selectNodes("//string");
    
        // No nodes are found, this is always zero
        Response.Write(nodes.length);
    
        for (var x = 0; x < nodes.length; x++) 
        {
            // Do something with each time zone value here
        }
    }
    

    有人能指出我做错了什么吗?非常感谢任何帮助!

    2 回复  |  直到 15 年前
        1
  •  1
  •   AnthonyWJones    15 年前

    SelectionNamespaces 属性来匹配文档的属性(当然,在可能的情况下使用相同的属性是有意义的)。

    按如下方式定义名称空间集:-

    var ns = "xmlns:a='http://api.createsend.com/api/' "
           + "xmlns:d1p1='http://www.w3.org/2001/XMLSchema-instance'"
    response.setProperty("SelectionNamespaces", ns);
    

    现在,您可以选择所有 string 包含以下内容的元素:-

    var nodes = response.selectNodes("//a:string");
    

    以下是我将如何将其作为一个整体进行编码:-

    var response = Server.CreateObject("MSXML2.DOMDocument.3.0");  // or use 6.0 but not 4.0
    response.async = false;
    response.validateOnParse = false;
    response.resolveExternals = false;
    
    
    response.setProperty("ServerHTTPRequest", true); 
    
    if (response.load(apiurl + "/User.GetTimezones?ApiKey=" + apikey)) 
    {
    
        var ns = "xmlns:a='http://api.createsend.com/api/' "
               + "xmlns:d1p1='http://www.w3.org/2001/XMLSchema-instance'"
        response.setProperty("SelectionNamespaces", ns);
    
        response.setProperty("SelectionLanguage", "XPath");  // remove for 4.0 or above is default
    
        var nodes = response.selectNodes("//a:string");
    
        Response.Write(nodes.length);
    
        for (var x = 0; x < nodes.length; x++) 
        {
            // Do something with each time zone value here
        }
    }
    

    • 对于GET请求,不需要使用单独的ServerXMLHttp对象,您可以通过启用 ServerHTTPRequest
    • 在4.0或更高版本上将SelectionLanguage指定为XPath是多余的,这是默认的选择语言。
        2
  •  2
  •   Tomalak    15 年前

    必须 使用前缀,即使它在XML中没有前缀:

    var nsDef = "";
    nsDef = nsDef + "xmlns:d1p1='http://www.w3.org/2001/XMLSchema-instance' ";
    nsDef = nsDef + "xmlns:api='http://api.createsend.com/api/' ";
    
    response.setProperty("SelectionNamespaces", nsDef);
    response.setProperty("SelectionLanguage", "XPath");
    
    var nodes = response.selectNodes("//api:string");
    

    如果不使用前缀,XPath表达式将在空命名空间中处理。这就是为什么您不能选择任何具有 "//string" .

    推荐文章