Источник:
http://axforum.info/forums/blog.php?b=391
==============
Вот уж не знаю что двигало разработчиками MS, когда они решили поддержать не все методы в веб сервисе REST. Казалось бы, спасибо и на том, что поддержали самые основные - CRUD. Раньше этого REST вообще не было, мы писали длиннющие портянки SOAP запросов, и ничего - жили как-то, справлялись.
Как вы могли догадаться, этот пост о том как сделать SOAP запрос к веб сервису CRM и обработать его результат в альтернативных браузерах... Послать сам запрос - не беда. Остается еще обработать результат. Разумеется можно воспользоваться кривыми примерами из SDK и потрошить XML через DOM. Однако я решил воспользоваться XPath. Вот тут-то и таилась засада...
Для выполнения XPath InternetExplorer использует нестандартные функции
X++:
selectSingleNode(xpathExpression)selectNodes(xpathExpression)
В то время как все остальные браузеры используют функцию:
X++:
document.evaluate(xpathExpression, contextNode, namespaceResolver, resultType, result)
Как видите это как раз тот случай, когда InternetExplorer стоит любить. Так вот формат в котором вываливается результат нашего SOAP запроса - это тот случай, когда любить Microsoft не стоит. Дело в том, что его XML изобилует кастомными неймспейсами, поддержки которых нет в методах IE, но к которым сторонние браузеры относятся очень чутко.
Результатом многочасовой отладки стал следующий код. Отдаю его без малейшего сожаления, а так же надеюсь что он спасет много жизней:
X++:
selectSingleNode: function (xmlDoc, elementPath, node) {
if (xmlDoc.evaluate) { function nsResolver(prefix) { var ns = {
"s":
"http://schemas.xmlsoap.org/soap/envelope/",
"i":
"http://www.w3.org/2001/XMLSchema-instance",
"a":
"http://schemas.microsoft.com/xrm/2011/Contracts",
"b":
"http://schemas.microsoft.com/xrm/2011/Contracts",
"c":
"http://schemas.datacontract.org/2004/07/System.Collections.Generic",
"d":
"http://www.w3.org/2001/XMLSchema" };
return ns[prefix] ||
null; } var nodes = xmlDoc.evaluate(elementPath, xmlDoc, node || nsResolver, XPathResult.ANY_TYPE,
null); var results = nodes.iterateNext();
return results; }
else return xmlDoc.selectSingleNode(elementPath); }
Пример использования:
X++:
var responseXml = req.responseXML;
// SOAP 1.1var faultCode = selectSingleNode(responseXml,
"//s:Envelope/s:Body/s:Fault/faultcode");
В том случае, когда надо получить дочерний элемент от уже полученного элемента, нужно передать его в качестве опционального параметра node:
X++:
var key = selectSingleNode(responseXml,
"//c:key", resultNode);
p.s. А вообще, если честно, при всем моем отношение к IE, как ужасному браузеру для серфинга, отладка в нем мне нравится куда больше чем в любимом ранее Firefox. Что кастомный Firebug, что встроенный отладчик ненесли по моей психике удар несовместимый с теми теплыми чувствами, которые я ранее испытывал к Mozilla. Кота названного в честь их браузера я переименовывать, конечно, не стану. Но впредь буду осторожнее ругать IE.
Источник:
http://axforum.info/forums/blog.php?b=391