lineage.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. /****************************************************************
  2. ** Licensed Materials - Property of IBM
  3. **
  4. ** IBM Cognos Products: mdsrv
  5. **
  6. ** (C) Copyright IBM Corp. 2008, 2016
  7. **
  8. ** US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. *****************************************************************/
  10. //***********************************************************************************************
  11. // Copyright (C) 2008 Cognos ULC, an IBM Company. All rights reserved.
  12. // Cognos (R) is a trademark of Cognos ULC, (formerly Cognos Incorporated).
  13. //***********************************************************************************************
  14. /** The CongnosConfiguration object, represents an object capable of holding the properties
  15. * contained in cognos configuartion. Currently the lineage solution only requires the URL
  16. * which is to be used to launch the lineage service, named "lineageURI" in cognos configuration.
  17. */
  18. function MDSRV_CognosConfiguration(){
  19. this.m_values = new Array(0);
  20. }
  21. /** Adds a property to the configuration. */
  22. MDSRV_CognosConfiguration.prototype.addProperty=function(key,value)
  23. {
  24. this.m_values[key]=value;
  25. }
  26. /** Retrieves a property from the configuration. */
  27. MDSRV_CognosConfiguration.prototype.getProperty=function(key)
  28. {
  29. return this.m_values[key];
  30. }
  31. /** XML Escapes a string */
  32. function MDSRV_EscapeXML(sInputString){
  33. var sOutputString = "" + sInputString;
  34. if ((sOutputString == '0') || ((sInputString != null) && (sInputString != false)))
  35. {
  36. //&
  37. sOutputString = sOutputString.replace(/&/g, "&");
  38. //<
  39. sOutputString = sOutputString.replace(/</g, "&lt;");
  40. //&gt;
  41. sOutputString = sOutputString.replace(/>/g, "&gt;");
  42. //&quot;
  43. sOutputString = sOutputString.replace(/"/g, "&quot;");
  44. //&apos;
  45. sOutputString = sOutputString.replace(/'/g, "&apos;");
  46. }
  47. else if (sInputString == null)
  48. {
  49. //return empty string if the value is null or false
  50. sOutputString = "";
  51. }
  52. return sOutputString;
  53. };
  54. /** This is the public api for lineage. This object should be constructed
  55. * by the viewer or studio.
  56. * @param cognosConfiguration - an object from which any property in the c8
  57. * configuration can be retrieved
  58. * [What type of object is cognosConfiguration?, Does such an object exist?
  59. * [If not then we need to change this to be the value of the lineageURL
  60. * from Cognos Configuration]
  61. */
  62. function MDSRV_LineageFragmentContext(cognosConfiguration, selectionContext)
  63. {
  64. this.m_reportPath="";
  65. this.m_packagePath="";
  66. this.m_metadataItems = new Array(0);
  67. this.m_executionParams="";
  68. this.m_configuration= cognosConfiguration;
  69. this.m_selectionContext = selectionContext;
  70. this.m_querySet = "";
  71. this.m_reportLineage = "";
  72. }
  73. /** @private */
  74. function MDSRV_LineageItem(id, query/*=null*/){
  75. this.m_queryItem = id;
  76. this.m_query = query;
  77. }
  78. /** @private */
  79. MDSRV_LineageItem.prototype.toFormXML=function()
  80. {
  81. var result = "<item";
  82. if (this.m_query){
  83. result += " queryRef='";
  84. //to do: these names should be xml escaped
  85. result += MDSRV_EscapeXML(this.m_query);
  86. result += "'"
  87. }
  88. result += ">";
  89. result += MDSRV_EscapeXML(this.m_queryItem);
  90. result += "</item>";
  91. return result;
  92. }
  93. /** Passes in the CM path of the report on which the lineage shall be executed. */
  94. MDSRV_LineageFragmentContext.prototype.setReportPath = function(reportPath)
  95. {
  96. this.m_reportPath=reportPath;
  97. }
  98. /** Passes in the Package path of the package on which the lineage shall be executed. */
  99. MDSRV_LineageFragmentContext.prototype.setPackagePath = function(packagePath)
  100. {
  101. this.m_packagePath= packagePath;
  102. }
  103. MDSRV_LineageFragmentContext.prototype.setQuerySet = function( querySet )
  104. {
  105. this.m_querySet = querySet;
  106. }
  107. MDSRV_LineageFragmentContext.prototype.setReportLineage = function( reportLineage )
  108. {
  109. this.m_reportLineage = reportLineage;
  110. }
  111. /** Passes in the item ID of an object whose lineage is to be retrieved. In the event
  112. * the item is from a report, then the query ID must also be passed in
  113. */
  114. MDSRV_LineageFragmentContext.prototype.addItem = function(queryItem, query/*=null*/){
  115. MDSRV_item = new MDSRV_LineageItem(queryItem, query);
  116. this.m_metadataItems.push(MDSRV_item);
  117. }
  118. /** Passes in the executionParameters. */
  119. MDSRV_LineageFragmentContext.prototype.setExecutionParameters = function(executionParams){
  120. this.m_executionParams = executionParams;
  121. }
  122. /* @private */
  123. MDSRV_LineageFragmentContext.prototype.getLineageRequestXML = function(){
  124. //the XML sent now conforms to the new drill through selection context, if we were giving a
  125. //selection context we use that, otherwise we buld up a fake one
  126. /*if (this.m_selectionContext){
  127. return this.m_selectionContext;
  128. }
  129. var context = new CSelectionContext(this.m_reportPath != "" ? this.m_reportPath : this.m_packagePath);
  130. for (i = 0; i < this.m_metadataItems.length; i++){
  131. context.addSelectedCell(this.m_metadataItems[i], this.m_metadataItems[i], "", "", this.m_metadataItems[i], "");
  132. }
  133. var res = context.toString();
  134. return res;
  135. */
  136. //add form field elements
  137. var xml = "<lineageInfo>";
  138. if (this.m_reportPath != ""){
  139. xml += "<reportPath>";
  140. xml += MDSRV_EscapeXML(this.m_reportPath);
  141. xml += "</reportPath>";
  142. }
  143. else if (this.m_packagePath != ""){
  144. xml += "<packagePath>";
  145. xml += MDSRV_EscapeXML(this.m_packagePath);
  146. xml += "</packagePath>";
  147. }
  148. else{
  149. throw "Expected report path or package path.";
  150. }
  151. for (i = 0; i < this.m_metadataItems.length; i++){
  152. xml += this.m_metadataItems[i].toFormXML();
  153. }
  154. xml += "</lineageInfo>";
  155. return xml;
  156. }
  157. //----------------------------------------------------------------------------------
  158. /** This API will submit the lineage request, and open it in a new window. */
  159. MDSRV_LineageFragmentContext.prototype.open = function( winName, winProperties )
  160. {
  161. //create a form to package all the data and then open it in the target
  162. var target = winName;
  163. var newWindow = null;
  164. var pid = "lineageMain";
  165. if (!winProperties){
  166. winProperties="menubar=no, resizable=yes,scrollbars=yes";
  167. }
  168. if (winName==null || winName=="_blank" || winName=="")
  169. {
  170. winName = "_blank";
  171. target = "_self";
  172. }
  173. if (! (winName=="_top" || winName=="_parent" || winName=="_self"))
  174. {
  175. newWindow = window.open("about:blank",winName,winProperties)
  176. newWindow.focus();
  177. }
  178. var docTarget = window.document;
  179. if (newWindow != null){
  180. docTarget = newWindow.document;
  181. }
  182. //fix for firefox, force the docTarget to be available
  183. docTarget.write("<HTML><HEAD></HEAD><BODY><div style='cursor:wait; width:100%; height:100%;'><div style='display:none;'>.</div></div></BODY></HTML>");
  184. docTarget.close();
  185. var formElement = docTarget.createElement("form");
  186. formElement.setAttribute("method","POST");
  187. formElement.setAttribute("target","_self");
  188. //get the URL for lineage from cognos configuration
  189. var lineageURI = this.m_configuration.getProperty("lineageURI");
  190. var gatewayURI = this.m_configuration.getProperty("gatewayURI");
  191. var targetAction = lineageURI;
  192. if (lineageURI.charAt(0) == '/'){
  193. targetAction = gatewayURI + lineageURI;
  194. }
  195. formElement.setAttribute("action", targetAction );
  196. //if we have a selectionContext convert it to metadata items
  197. //convertSelectionContext();
  198. if ( this.m_selectionContext )
  199. {
  200. // alert ( "selectionContext = " + this.m_selectionContext );
  201. var lineageRequestElement = docTarget.createElement("input");
  202. lineageRequestElement.setAttribute("type","hidden");
  203. lineageRequestElement.setAttribute("name","selectioncontext");
  204. lineageRequestElement.setAttribute("value",this.m_selectionContext);
  205. formElement.appendChild(lineageRequestElement);
  206. }
  207. else
  208. {
  209. var lineageRequestElement = docTarget.createElement("input");
  210. lineageRequestElement.setAttribute("type","hidden");
  211. lineageRequestElement.setAttribute("name","lineagerequest");
  212. lineageRequestElement.setAttribute("value",this.getLineageRequestXML());
  213. formElement.appendChild(lineageRequestElement);
  214. }
  215. var hiddenElement1 = docTarget.createElement("input");
  216. hiddenElement1.setAttribute("type","hidden");
  217. hiddenElement1.setAttribute("name","pid");
  218. hiddenElement1.setAttribute("value","progress_pid");
  219. formElement.appendChild(hiddenElement1);
  220. var primaryPidElement = docTarget.createElement("input");
  221. primaryPidElement.setAttribute("type","hidden");
  222. primaryPidElement.setAttribute("name","primary_pid");
  223. primaryPidElement.setAttribute("value",pid);
  224. formElement.appendChild(primaryPidElement);
  225. var hiddenElement2 = docTarget.createElement("input");
  226. hiddenElement2.setAttribute("type","hidden");
  227. hiddenElement2.setAttribute("name","executionParams");
  228. hiddenElement2.setAttribute("value",this.m_executionParams);
  229. formElement.appendChild(hiddenElement2);
  230. if ( this.m_querySet.length > 0 )
  231. {
  232. // alert ( "querySet = " + this.m_querySet );
  233. var hiddenElement3 = docTarget.createElement("input");
  234. hiddenElement3.setAttribute("type","hidden");
  235. hiddenElement3.setAttribute("name","querySet");
  236. hiddenElement3.setAttribute("value",this.m_querySet);
  237. formElement.appendChild( hiddenElement3 );
  238. }
  239. if ( this.m_reportLineage.length > 0 )
  240. {
  241. // alert ( "reportLineage = " + this.m_reportLineage );
  242. var hiddenElement4 = docTarget.createElement("input");
  243. hiddenElement4.setAttribute("type","hidden");
  244. hiddenElement4.setAttribute("name","reportLineage");
  245. hiddenElement4.setAttribute("value",this.m_reportLineage);
  246. formElement.appendChild( hiddenElement4 );
  247. }
  248. var closeWindowElement = docTarget.createElement("input");
  249. closeWindowElement.setAttribute("type", "hidden");
  250. closeWindowElement.setAttribute("name", "errURL");
  251. closeWindowElement.setAttribute("value", "javascript:window.close()");
  252. formElement.appendChild(closeWindowElement);
  253. // Submit form
  254. docTarget.body.appendChild(formElement);
  255. formElement.submit();
  256. docTarget.body.removeChild(formElement);
  257. formElement = null;
  258. }
  259. //-----------------------------------------------------------------------
  260. //Busines glossary api
  261. //-----------------------------------------------------------------------
  262. /**The MDSRV_BusinessGlossary object can be used to invoke lineage.
  263. *@param cogonsConfiguration [mandatory] - A MDSRV_CognosConfiguration object which must contain
  264. * the configured business glossary URL. Name is "glossaryURI" and must point to the glossary URI that is configured in CM as a sytem level property.
  265. *
  266. *@param selectionContext [optional] - a selection context representing the selected item
  267. */
  268. function MDSRV_BusinessGlossary(cognosConfiguration, selectionContext)
  269. {
  270. this.m_cognosConfiguration = cognosConfiguration;
  271. this.m_selectionContext = selectionContext;
  272. this.m_terms = new Array();
  273. }
  274. MDSRV_BusinessGlossary.prototype.returnValue =
  275. {
  276. success: 1,
  277. noTermsSpecified: 2,
  278. noCognosConfiguration: 3,
  279. noGlossaryURI: 4
  280. }
  281. /** This method should be called when a selectionContext was not provide to the business glossary.
  282. * The term passed in should be the localized name of the object as it was displayed in the metadata
  283. * tree. This is NOT an id, it is striclty the display name of the item that was selected.
  284. */
  285. MDSRV_BusinessGlossary.prototype.addTerm = function(term)
  286. {
  287. this.m_terms.push(term);
  288. }
  289. /** Call this method to launch the business glossary. This method must be called
  290. * after any addTerm() calls, if no selection context has been specified.
  291. * Return Value: one of the values from the MDSRV_BusinessGlossary.returnValue
  292. */
  293. MDSRV_BusinessGlossary.prototype.open = function( winName, winProperties )
  294. {
  295. if ( this.m_cognosConfiguration == undefined )
  296. return this.returnValue.noCognosConfiguration;
  297. // Get the business glossary URI out of the configuration
  298. var targetAction = this.m_cognosConfiguration.getProperty("glossaryURI");
  299. if ( ! targetAction )
  300. return this.returnValue.noGlossaryURI;
  301. // Parse the Selection Context and prepare data for the Business Glossary
  302. if ( this.m_selectionContext )
  303. {
  304. this.parseTerms( this.m_selectionContext );
  305. }
  306. // alert( "Count of TERMs: " + this.m_terms.length );
  307. if ( this.m_terms.length < 1 )
  308. {
  309. return this.returnValue.noTermsSpecified;
  310. }
  311. // Open the Business Glossary window and submit the formatted data
  312. var target = winName;
  313. var newWindow = null;
  314. if ( ! winProperties )
  315. {
  316. winProperties = "menubar=no, toolbar=no, location=no, resizable=yes,scrollbars=yes";
  317. }
  318. if ( winName==null || winName=="_blank" || winName=="" )
  319. {
  320. winName = "_blank";
  321. target = "_self";
  322. }
  323. if ( ! ( winName=="_top" || winName=="_parent" || winName=="_self" ) )
  324. {
  325. newWindow = window.open("about:blank",winName,winProperties)
  326. newWindow.focus();
  327. }
  328. var docTarget = window.document;
  329. if ( newWindow != null )
  330. {
  331. docTarget = newWindow.document;
  332. }
  333. //fix for firefox, force the docTarget to be available
  334. docTarget.write("<HTML><HEAD></HEAD><BODY><div style='cursor:wait; width:100%; height:100%;'><div style='display:none;'>.</div></div></BODY></HTML>");
  335. docTarget.close();
  336. var formElement = docTarget.createElement("form");
  337. formElement.setAttribute("name","MDSRV_BUSGLOSSARY");
  338. formElement.setAttribute("method","GET");
  339. formElement.setAttribute("target","_self");
  340. //any URL parameters that were put we need to pull out and pass along
  341. var questIdx = targetAction.indexOf("?");
  342. if ( questIdx != -1 )
  343. {
  344. if (questIdx + 1 < targetAction.length)
  345. {
  346. var params = targetAction.substring(questIdx+1);
  347. targetAction = targetAction.substring(0, questIdx);
  348. var eqIndex = params.indexOf("=");
  349. while (eqIndex != -1)
  350. {
  351. var nm = params.substring(0, eqIndex);
  352. var vl = null;
  353. var ampIdx = params.indexOf("&");
  354. if (ampIdx != -1)
  355. {
  356. vl = params.substring(eqIndex+1, ampIdx);
  357. params = params.substring(ampIdx+1);
  358. eqIndex = params.indexOf("&");
  359. }
  360. else
  361. {
  362. vl = params.substring(eqIndex+1);
  363. eqIndex = -1;
  364. }
  365. if (vl != null)
  366. {
  367. var custom = docTarget.createElement("input");
  368. custom.setAttribute("type", "hidden");
  369. custom.setAttribute("name", nm);
  370. custom.setAttribute("value", vl);
  371. formElement.appendChild(custom);
  372. }
  373. }
  374. }
  375. }
  376. formElement.setAttribute("action", targetAction );
  377. var searchBy = docTarget.createElement("input");
  378. searchBy.setAttribute("type", "hidden");
  379. searchBy.setAttribute("name", "searchBy");
  380. searchBy.setAttribute("value", "Terms");
  381. formElement.appendChild(searchBy);
  382. for (var i = 0; i < this.m_terms.length; i++)
  383. {
  384. var glossaryRequestElement = docTarget.createElement("input");
  385. glossaryRequestElement.setAttribute("type","hidden");
  386. glossaryRequestElement.setAttribute("name","searchText");
  387. glossaryRequestElement.setAttribute("value",this.m_terms[i]);
  388. formElement.appendChild(glossaryRequestElement);
  389. }
  390. docTarget.body.appendChild(formElement);
  391. formElement.submit();
  392. docTarget.body.removeChild(formElement);
  393. formElement = null;
  394. return this.returnValue.success;
  395. }
  396. /** @private
  397. *
  398. * Parses the terms out of the given selection context.
  399. */
  400. MDSRV_BusinessGlossary.prototype.parseTerms = function( selectionContext )
  401. {
  402. // alert ( "Selection Context = " + selectionContext );
  403. var api = new MDSRV_xmlAPI(selectionContext);
  404. api.addNamespace('s', 'http://developer.cognos.com/schemas/selection/1/');
  405. var context = api.getRootElement();
  406. var node = api.selectSingleNode(context, "//s:selection");
  407. var selectedCells = node.getAttribute("rSelectedCells");
  408. var nodeCells = new Array();
  409. api.selectNodes(context, "/s:selection/s:cells/s:cell", nodeCells);
  410. //the selected cells are space seperated
  411. if ( selectedCells )
  412. {
  413. var cellsList = selectedCells.split(" ");
  414. for ( i = 0; i < cellsList.length; i++ )
  415. {
  416. //find the selected cell
  417. var selectedCell=null;
  418. for (cellIdx=0; !selectedCell && cellIdx < nodeCells.length; cellIdx++)
  419. {
  420. var atts = nodeCells[cellIdx].attributes;
  421. //to tell if its the cell we have to look at its xml:id
  422. for (attIdx = 0; attIdx < atts.length; attIdx++)
  423. {
  424. if (atts[attIdx].name == 'xml:id' && atts[attIdx].value == cellsList[i])
  425. {
  426. selectedCell=nodeCells[cellIdx];
  427. break;
  428. }
  429. }
  430. }
  431. if ( selectedCell )
  432. {
  433. var term = selectedCell.getAttribute("display");
  434. if ( term )
  435. {
  436. this.addTerm(term);
  437. }
  438. }
  439. }
  440. }
  441. }
  442. //XML Processing methods
  443. /**
  444. * @private
  445. * Constructs an object used to process an arbitrary xml string.
  446. */
  447. function MDSRV_xmlAPI(xmlText){
  448. this.m_xmlDoc="";
  449. this.m_isActiveX=false;
  450. this.m_namespaces = new Array();
  451. try{
  452. if (document.createExpression) { // for all browsers but IE
  453. var parser=new DOMParser();
  454. this.m_xmlDoc=parser.parseFromString(xmlText,"text/xml");
  455. }
  456. else{ // for IE
  457. this.m_xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  458. this.m_xmlDoc.setProperty("SelectionLanguage", "XPath");
  459. this.m_xmlDoc.async="false";
  460. //IE will yack if there is xmlns:xml declaration so we have to rip it out
  461. xmlText = xmlText.replace("xmlns:xml", "xmlns:blah");
  462. this.m_xmlDoc.loadXML(xmlText);
  463. if (this.m_xmlDoc.parseError.errorCode != 0) {
  464. var myErr = this.m_xmlDoc.parseError;
  465. alert( "Error parsing the XML document: " + xmlText + ", reason: " + myErr.reason );
  466. }
  467. this.m_isActiveX=true;
  468. }
  469. }
  470. catch (err){
  471. alert( "Could not parse the XML document: " + xmlText + ", description: " + err.description );
  472. }
  473. }
  474. /**
  475. * @private
  476. *
  477. * Adds the namespace of with the given prefix and uri to this object.
  478. */
  479. MDSRV_xmlAPI.prototype.getRootElement = function(){
  480. if (this.m_xmlDoc.documentElement){
  481. return this.m_xmlDoc.documentElement;
  482. }
  483. return this.m_xmlDoc;
  484. }
  485. /**
  486. * @private
  487. *
  488. * Creates a namespace with the given prefix and mapped uri.
  489. */
  490. MDSRV_xmlAPI.prototype.createNamespace = function( prefix )
  491. {
  492. var str = "";
  493. if ( typeof prefix == "string" )
  494. {
  495. var uri = this.m_namespaces[ prefix ];
  496. if ( typeof uri == "string" )
  497. {
  498. if ( uri.indexOf( "http:" ) != -1 )
  499. {
  500. str += "xmlns:";
  501. str += prefix;
  502. str += "='";
  503. str += uri;
  504. str += "'";
  505. }
  506. }
  507. }
  508. return str;
  509. }
  510. /**
  511. * @private
  512. *
  513. * Adds the namespace of with the given prefix and uri to this object.
  514. */
  515. MDSRV_xmlAPI.prototype.addNamespace = function( prefix, uri )
  516. {
  517. this.m_namespaces[ prefix ] = uri;
  518. if ( this.m_isActiveX )
  519. {
  520. var str = "";
  521. for ( var ns in this.m_namespaces )
  522. {
  523. var sNamespace = this.createNamespace( ns );
  524. if ( sNamespace.length > 0 )
  525. {
  526. if ( str.length > 0 )
  527. str += " "; // the list of namespaces must be space-separated
  528. str += sNamespace;
  529. }
  530. }
  531. this.m_xmlDoc.setProperty( "SelectionNamespaces", str );
  532. }
  533. }
  534. /**
  535. * @private
  536. *
  537. * Selects a single node, as specified by the given xpath.
  538. * @param contextNode a XMLElement on which the xpath should be executed
  539. * @param xpath the xpath string to be executed
  540. *
  541. * @return a single node which satisifes the xpath
  542. *
  543. *
  544. */
  545. MDSRV_xmlAPI.prototype.selectSingleNode = function(contextNode, xpath){
  546. var node;
  547. var namespaces=this.m_namespaces;
  548. //firefox
  549. if (document.createExpression){
  550. var result = this.m_xmlDoc.evaluate(xpath, contextNode,
  551. function(prefix) {
  552. return namespaces[prefix];
  553. }
  554. , XPathResult.ANY_TYPE, null);
  555. node = result.iterateNext();
  556. }
  557. else{//ie
  558. node = contextNode.selectSingleNode(xpath);
  559. }
  560. return node;
  561. }
  562. /**
  563. * @private
  564. *
  565. * Selects all the nodes which satisfy the given xpath.
  566. * @param contextNode a XMLElement on which the xpath should be executed
  567. * @param xpath the xpath string to be executed
  568. * @param resultNodes, an array into which the results will be added
  569. */
  570. MDSRV_xmlAPI.prototype.selectNodes = function(contextNode, xpath, resultNodes){
  571. var namespaces=this.m_namespaces;
  572. //firefox
  573. if (document.createExpression){
  574. var result = this.m_xmlDoc.evaluate(xpath, contextNode,
  575. function(prefix) {
  576. return namespaces[prefix];
  577. }
  578. , XPathResult.ANY_TYPE, null);
  579. var node = result.iterateNext();
  580. while (node){
  581. resultNodes.push(node);
  582. node = result.iterateNext();
  583. }
  584. }
  585. else{//ie
  586. var nodeList = contextNode.selectNodes(xpath);
  587. for (i = 0; i < nodeList.length; i++){
  588. resultNodes.push(nodeList[i]);
  589. }
  590. }
  591. }