2009-12-07 2 views
1

ОК, я нахожусь в своем уме. Кажется, это должно быть совершенно тривиальной задачей, но через час я все еще просто не могу заставить ее работать.Как я могу получить узлы XML из этого XML в классическом ASP (MSXML)?

Я пытаюсь получить список часовых поясов от 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 
    } 
} 

Проблема, как вы можете видеть из комментариев, состоит в том, что я не могу показаться, string ", независимо от того, что я делаю. Я довольно ржавый, когда дело доходит до ASP/Javascript - я подозреваю, что это что-то делать с пространствами имен (я знаю, что у меня были проблемы с этим в прошлом), но я не уверен, что.

Может ли кто-нибудь указать, что я делаю неправильно? Любая помощь очень ценится!

ответ

1

Вы не можете переопределить пространство имен по умолчанию, используемое XPath. В MSXML пространство имен по умолчанию XPath всегда является пространством имен «без имени». Однако нет необходимости в наборе псевдонимов, используемых в свойстве 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, вы можете проинструктировать DOMDocument использовать ServerXMLHttp внутри, включив свойство ServerHTTPRequest. (Кстати, ваш код, по-видимому, перенаправляет DOMDocument с помощью свойства ResponseXML в новый DOMDocument).
  • Я предпочитаю использовать версию MSXML версии 3.0, так как гарантированно будет присутствовать на поддерживаемых платформах. Если нет, я бы установил 6.0 и использовал это.
  • Задание языка выбора для XPath версии 4.0 или выше избыточно, это язык выбора по умолчанию.
+0

Похоже, что в моем знании XML есть немного пробела, лучше всего читать! Все работают сейчас, очень благодарны, спасибо. –

2

Ваше заблуждение относится к обработке пространства имен по умолчанию. Там нет такого понятия, как пространство имен по умолчанию для XPath выражений здесь - вы должны использовать префикс, даже если он не имеет префикс в 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".

+0

Я боюсь дать ответ Энтони, потому что он немного подошел и не по вызову, но благодарит за вашу помощь! –

Смежные вопросы