如何在经典ASP(MSXML)中从该XML获取XML节点? [英] How can I get the XML nodes from this XML in classic ASP (MSXML)?

查看:98
本文介绍了如何在经典ASP(MSXML)中从该XML获取XML节点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我机智了.看来这应该是一件微不足道的事情,但是一个小时后,我仍然无法使其正常工作.

OK, I'm at my wits end. This seems like it should be a completely trivial thing to do, yet after an hour I still just cannot make it work.

我正在尝试从广告系列监控器API获取时区列表;不幸的是,我需要执行此操作的页面是用经典的ASP/Javascript编写的,所以我不能只使用API​​包装器.

I'm trying to get a list of time zones from the Campaign Monitor API; unfortunately the page I need to do this in is written in classic ASP/Javascript so I can't just use the API wrapper.

我正在这样发出请求:

var request = Server.CreateObject("Msxml2.ServerXMLHTTP");

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

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

The correct XML is coming back from the server, as follows:

<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文档中:

Then I am loading this XML into an MSXML document:

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
    }
}

正如您从注释中看到的那样,问题是无论执行什么操作,我似乎都无法匹配那些字符串"节点.对于ASP/Javascript,我非常生锈-我怀疑这与名称空间有关(我知道我过去曾经对此有问题),但我不确定是什么.

The problem, as you can see from the comments, is that I can't seem to match those 'string' nodes no matter what I do. I'm pretty rusty when it comes to ASP/Javascript - I suspect it's something do do with the namespaces (I know I had problems with this in the past), but I'm not sure what.

谁能指出我做错了什么?任何帮助,不胜感激!

Can anyone point out what I'm doing wrong? Any help much appreciated!

推荐答案

您不能覆盖XPath使用的默认名称空间.在MSXML中,XPath默认名称空间始终是无名称"名称空间.但是,不需要SelectionNamespaces属性中使用的别名集来匹配文档中的别名(尽管当然可以在可能的情况下使用相同的别名).

You cannot override the default namespace used by XPath. In MSXML the XPath default namespace is always the "no name" namespace. However there is no need for the set of aliases used in the SelectionNamespaces property to match those of the document (although of course it makes sense where possible to use the same ones).

这样定义您的命名空间集:-

Define your set of namespaces like this:-

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

现在,您可以使用以下命令选择所有string元素:-

Now you can select all the string elements with:-

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

这就是我整体编码的方式:-

This is how I would code this as a whole:-

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属性来指示DOMDocument在内部使用ServerXMLHttp. (顺便说一句,您的代码似乎是在冗余地将由ResponseXML属性公开的DOMDocument流式传输到新的DOMDocument中).
  • 我更喜欢使用3.0版本的MSXML,因为可以确保该版本存在于受支持的平台上.如果没有,那么我将安装6.0并使用它.
  • 将SelectionLanguage指定为4.0或更高版本的XPath是多余的,这是默认选择语言.
  • For a GET request there is no need to use a separate ServerXMLHttp object, you can instruct the DOMDocument to use ServerXMLHttp internally when by enabling the ServerHTTPRequest property. (BTW, your code seems to be reduntantly streaming the DOMDocument exposed in by the ResponseXML property into a new DOMDocument).
  • I prefer to use the 3.0 version of MSXML since that is guaranteed to be present on supported platforms. If not then I would install 6.0 and use that.
  • Specifying the SelectionLanguage to be XPath on 4.0 or above is redundant, its the default selection language.

这篇关于如何在经典ASP(MSXML)中从该XML获取XML节点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆