XMLParser.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /*
  2. *+------------------------------------------------------------------------+
  3. *| Licensed Materials - Property of IBM
  4. *| IBM Cognos Products: Viewer
  5. *| (C) Copyright IBM Corp. 2001, 2014
  6. *|
  7. *| US Government Users Restricted Rights - Use, duplication or
  8. *| disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. *|
  10. *+------------------------------------------------------------------------+
  11. */
  12. function XMLParser(s, parent)
  13. {
  14. if (s == null) {
  15. return null;
  16. }
  17. if (/^\s*</.test(s)) {
  18. // remove leading spaces
  19. s = s.replace(/^\s*/, '');
  20. if (s.charAt(1) == '/') {
  21. // end of an element
  22. var reParent = new RegExp("^</" + parent.getName() + "\\s*>", "gi");
  23. if (!reParent.test(s)) {
  24. alert("invalid XML " + parent.getName() + "\n" + s);
  25. return null;
  26. }
  27. return XMLParser(s.replace(RegExp.lastMatch,""), parent.parentNode);
  28. }
  29. else {
  30. // new element
  31. var reNewElement = /^\s*<([\w:\-_\.]+)/;
  32. if ( reNewElement.test(s) ) {
  33. var nodeName = RegExp.$1;
  34. var e = new XMLElement(nodeName, parent);
  35. var patternToRemove = new RegExp("^<" + nodeName + "[^>]*>");
  36. s = s.replace(patternToRemove, "");
  37. var currentNodeText = RegExp.lastMatch;
  38. var attributesPattern = /([\w:\-_\.]+)="([^"]*)"/gi;
  39. var attrMatches = currentNodeText.match(attributesPattern);
  40. if (attrMatches != null) {
  41. for (var i=0; i<attrMatches.length; i++) {
  42. var attrText = attrMatches[i];
  43. (/([\w:\-_\.]+)\s*=\s*"(.*)"/).test(attrText);
  44. e.setAttribute(RegExp.$1, RegExp.$2);
  45. }
  46. }
  47. if ( ! (/\/>$/).test(currentNodeText) ) {
  48. XMLParser(s, e);
  49. return e;
  50. }
  51. else {
  52. XMLParser(s, parent);
  53. return e;
  54. }
  55. }
  56. }
  57. }
  58. else {
  59. // text node
  60. if (s && parent)
  61. {
  62. var textNodePattern = new RegExp("([^<]*)</" + parent.getName() + "\\s*[^>]*>", "gi");
  63. textNodePattern.test(s);
  64. var nodeValue = RegExp.$1;
  65. parent.setValue(nodeValue);
  66. return (XMLParser(s.replace(nodeValue, ""), parent));
  67. }
  68. }
  69. return null;
  70. }
  71. function XMLElement(s, parent)
  72. {
  73. this.nodeName = s;
  74. this.nodeValue = "";
  75. this.attributes = [];
  76. this.childNodes = [];
  77. this.parentNode = parent;
  78. if (this.parentNode) {
  79. this.parentNode.appendChild(this);
  80. }
  81. }
  82. XMLElement.prototype.appendChild = function (e) { this.childNodes[this.childNodes.length] = e; };
  83. XMLElement.prototype.hasChildNodes = function ()
  84. {
  85. if (this.childNodes.length > 0) {
  86. return true;
  87. }
  88. else {
  89. return false;
  90. }
  91. };
  92. XMLElement.prototype.findChildByName = function (n, deepWalk)
  93. {
  94. if (this.getName() == n) {
  95. return(this);
  96. }
  97. for (var i = 0; i < this.childNodes.length; i++) {
  98. if (this.childNodes[i].getName() == n) {
  99. return this.childNodes[i];
  100. }
  101. }
  102. if (deepWalk != false) {
  103. for (i = 0; i < this.childNodes.length; i++) {
  104. var foundChild = this.childNodes[i].findChildByName(n, deepWalk);
  105. if (foundChild) {
  106. return foundChild;
  107. }
  108. }
  109. }
  110. return null;
  111. };
  112. XMLElement.prototype.findChildWithAttribute = function (attr, val)
  113. {
  114. for (var i = 0; i < this.childNodes.length; i++) {
  115. if (this.childNodes[i].getAttribute(attr) == val) {
  116. return this.childNodes[i];
  117. }
  118. }
  119. return null;
  120. };
  121. XMLElement.prototype.getElementsByTagName = function (s, deep)
  122. {
  123. var a = [];
  124. for (var i = 0; i < this.childNodes.length; i++) {
  125. if (this.childNodes[i].getName() == s) {
  126. a[a.length] = this.childNodes[i];
  127. }
  128. }
  129. if (deep != false) {
  130. for (i = 0; i < this.childNodes.length; i++) {
  131. var aChild = this.childNodes[i].getElementsByTagName(s);
  132. for (var j = 0; j < aChild.length; j++) {
  133. a[a.length] = aChild[j];
  134. }
  135. }
  136. }
  137. return a;
  138. };
  139. XMLElement.prototype.getName = function () { return this.nodeName; };
  140. XMLElement.prototype.getValue = function () { return this.nodeValue; };
  141. XMLElement.prototype.setAttribute = function (a, v) { this.attributes["_" + a] = v; };
  142. XMLElement.prototype.setValue = function (v) { this.nodeValue = v; };
  143. XMLElement.prototype.getAttribute = function (a)
  144. {
  145. var retval = "";
  146. if (typeof sXmlDecode == "function")
  147. {
  148. retval = sXmlDecode(this.attributes["_" + a]);
  149. }
  150. else
  151. {
  152. retval = this.attributes["_" + a];
  153. }
  154. return (retval == null ? "" : retval);
  155. };
  156. XMLElement.prototype.toString = function()
  157. {
  158. var s = "<" + this.getName();
  159. for (var i in this.attributes) {
  160. s += " " + i.substring(1) + "=\"" + this.attributes[i] + "\"";
  161. }
  162. s += ">" + this.getValue();
  163. for (var j = 0; j < this.childNodes.length; j++) {
  164. s += this.childNodes[j].toString();
  165. }
  166. s += "</" + this.getName() + ">";
  167. return s;
  168. };
  169. function XMLBuilderLoadXMLFromString (markup, forceDOMParserIfAvailable)
  170. {
  171. var xmlDocument = null;
  172. if (typeof DOMParser != 'undefined')
  173. {
  174. xmlDocument = new DOMParser().parseFromString(markup, 'application/xml');
  175. }
  176. else if (typeof ActiveXObject != 'undefined')
  177. {
  178. try
  179. {
  180. xmlDocument = new ActiveXObject('Microsoft.XMLDOM');
  181. xmlDocument.loadXML(markup);
  182. }
  183. catch (e)
  184. {
  185. }
  186. }
  187. return xmlDocument;
  188. }
  189. function XMLBuilderCreateXMLDocument (rootElementName, namespaceURI, documentType)
  190. {
  191. var xmlDocument = null;
  192. namespaceURI = namespaceURI || '';
  193. documentType = documentType || null;
  194. if (document.implementation && document.implementation.createDocument)
  195. {
  196. if (typeof namespaceURI == "undefined") {
  197. namespaceURI = "http://www.w3.org/2000/xmlns/";
  198. }
  199. xmlDocument = document.implementation.createDocument(namespaceURI, rootElementName, documentType);
  200. }
  201. else if (typeof ActiveXObject != 'undefined')
  202. {
  203. try
  204. {
  205. xmlDocument = new ActiveXObject('Microsoft.XMLDOM');
  206. var rootElement = xmlDocument.createNode(1, rootElementName, namespaceURI);
  207. xmlDocument.appendChild(rootElement);
  208. }
  209. catch (e)
  210. {
  211. }
  212. }
  213. return xmlDocument;
  214. }
  215. function XMLBuilderCreateElementNS (namespaceURI, elementName, ownerDocument)
  216. {
  217. var element = null;
  218. if (typeof ownerDocument.createElementNS != 'undefined')
  219. {
  220. if (typeof namespaceURI == "undefined") {
  221. namespaceURI = "http://www.w3.org/2000/xmlns/";
  222. }
  223. element = ownerDocument.createElementNS(namespaceURI, elementName);
  224. }
  225. else if (typeof ownerDocument.createNode != 'undefined')
  226. {
  227. element = ownerDocument.createNode(1, elementName, namespaceURI);
  228. }
  229. return element;
  230. }
  231. function XMLBuilderSetAttributeNodeNS (element, attributeName, attributeValue, namespaceURI)
  232. {
  233. if (typeof element.setAttributeNS != 'undefined')
  234. {
  235. if (typeof namespaceURI == "undefined") {
  236. namespaceURI = "http://www.w3.org/2000/xmlns/";
  237. }
  238. element.setAttributeNS(namespaceURI, attributeName, attributeValue);
  239. }
  240. else if (typeof element.ownerDocument != 'undefined' && typeof element.ownerDocument.createNode != 'undefined')
  241. {
  242. var attribute = element.ownerDocument.createNode(2, attributeName, namespaceURI);
  243. attribute.nodeValue = attributeValue;
  244. element.setAttributeNode(attribute);
  245. }
  246. }
  247. function XMLBuilderSerializeNode (node)
  248. {
  249. var sXml = "";
  250. if (typeof XMLSerializer != 'undefined')
  251. {
  252. try
  253. {
  254. sXml = new XMLSerializer().serializeToString(node);
  255. }
  256. catch (e)
  257. {
  258. //Can end up here if the node was not an XML object
  259. }
  260. }
  261. else if (typeof node == "object" && typeof node.xml != 'undefined')
  262. {
  263. sXml = node.xml;
  264. }
  265. return sXml.replace(/^\s+/g, "").replace(/\s+$/g, "");
  266. }
  267. function XMLHelper_GetText(node, bDeepWalk)
  268. {
  269. var text="";
  270. var childNodes = node.childNodes;
  271. for(var i = 0; i < childNodes.length; ++i)
  272. {
  273. if(childNodes[i].nodeType == 3)
  274. {
  275. text += childNodes[i].nodeValue;
  276. }
  277. else if (childNodes[i].nodeName == "Value")
  278. {
  279. text += childNodes[i].getAttribute("display");
  280. }
  281. else if (bDeepWalk)
  282. {
  283. text += XMLHelper_GetText(childNodes[i], true);
  284. }
  285. }
  286. return text;
  287. }
  288. function XMLHelper_GetLocalName(node)
  289. {
  290. if(typeof node.baseName != "undefined") {
  291. return node.baseName;
  292. }
  293. return node.localName;
  294. }
  295. function XMLHelper_FindChildByTagName(node, name, deepWalk)
  296. {
  297. // validate deep walk argument (must be "true" or "false")
  298. if (typeof deepWalk == "undefined" || (deepWalk != true && deepWalk != false)) {
  299. deepWalk = true;
  300. }
  301. if (XMLHelper_GetLocalName(node) == name)
  302. {
  303. return(node);
  304. }
  305. var i;
  306. for (i = 0; i < node.childNodes.length; i++)
  307. {
  308. if (XMLHelper_GetLocalName(node.childNodes[i]) == name)
  309. {
  310. return node.childNodes[i];
  311. }
  312. }
  313. if (deepWalk != false)
  314. {
  315. for (i = 0; i < node.childNodes.length; i++)
  316. {
  317. var foundChild = XMLHelper_FindChildByTagName(node.childNodes[i], name, deepWalk);
  318. if (foundChild)
  319. {
  320. return foundChild;
  321. }
  322. }
  323. }
  324. return null;
  325. }
  326. function XMLHelper_FindChildrenByTagName(oNode, sName, bDeepWalk)
  327. {
  328. // validate deep walk argument (must be "true" or "false")
  329. if (typeof bDeepWalk == "undefined" || (bDeepWalk != true && bDeepWalk != false))
  330. {
  331. bDeepWalk = true;
  332. }
  333. var aFoundNodes = [];
  334. var oNodeChildren = oNode.childNodes;
  335. for (var idxChildNodes = 0; idxChildNodes < oNodeChildren.length; idxChildNodes++)
  336. {
  337. if (XMLHelper_GetLocalName(oNodeChildren[idxChildNodes]) == sName)
  338. {
  339. aFoundNodes[aFoundNodes.length] = oNodeChildren[idxChildNodes];
  340. }
  341. if (bDeepWalk === true)
  342. {
  343. var oFoundChildren = XMLHelper_FindChildrenByTagName(oNodeChildren[idxChildNodes], sName, bDeepWalk);
  344. if (oFoundChildren.length > 0)
  345. {
  346. aFoundNodes = aFoundNodes.concat(oFoundChildren);
  347. }
  348. }
  349. }
  350. return aFoundNodes;
  351. }
  352. function XMLHelper_GetFirstChildElement( oEl )
  353. {
  354. var oChild = null;
  355. if ( oEl && oEl.childNodes && oEl.childNodes.length )
  356. {
  357. for ( var i = 0; i < oEl.childNodes.length; i++ )
  358. {
  359. if ( oEl.childNodes[i].nodeType == 1 )
  360. {
  361. oChild = oEl.childNodes[i];
  362. break;
  363. }
  364. }
  365. }
  366. return oChild;
  367. }
  368. function XMLHelper_FindChildrenByAttribute(oNode, sName, sValue, bDeepWalk, bGetOnlyFirstChild)
  369. {
  370. // validate deep walk argument (must be "true" or "false")
  371. if (typeof bDeepWalk == "undefined" || (bDeepWalk != true && bDeepWalk != false))
  372. {
  373. bDeepWalk = true;
  374. }
  375. if (typeof sValue != "string" && typeof sValue != "number")
  376. {
  377. sValue = null;
  378. }
  379. else
  380. {
  381. sValue = sValue.toString();
  382. }
  383. var aFoundNodes = [];
  384. var oNodeChildren = oNode.childNodes;
  385. for (var idxChildNodes = 0; idxChildNodes < oNodeChildren.length; idxChildNodes++)
  386. {
  387. var oChild = oNodeChildren[idxChildNodes];
  388. if (oChild.nodeType == 1)
  389. {
  390. var sNodeAttr = oChild.getAttribute(sName);
  391. if (sNodeAttr !== null)
  392. {
  393. if (sValue === null || sNodeAttr == sValue)
  394. {
  395. if (bGetOnlyFirstChild)
  396. {
  397. return [oChild];
  398. }
  399. else
  400. {
  401. aFoundNodes[aFoundNodes.length] = oChild;
  402. }
  403. }
  404. }
  405. if (bDeepWalk === true)
  406. {
  407. var oFoundChildren = XMLHelper_FindChildrenByAttribute(oChild, sName, sValue, bDeepWalk, bGetOnlyFirstChild);
  408. if (oFoundChildren.length > 0)
  409. {
  410. if (bGetOnlyFirstChild)
  411. {
  412. if (oFoundChildren.length == 1)
  413. {
  414. return oFoundChildren;
  415. }
  416. else
  417. {
  418. return [oFoundChildren[0]];
  419. }
  420. }
  421. else
  422. {
  423. aFoundNodes = aFoundNodes.concat(oFoundChildren);
  424. }
  425. }
  426. }
  427. }
  428. }
  429. return aFoundNodes;
  430. }
  431. /*
  432. Here are a few examples of how to use the XMLBuilder:
  433. First you need to create an XML Document. This document INCLUDES the root node of the XML.
  434. var rootElement = XMLBuilderCreateXMLDocument("root", "");
  435. --> Here we're not specifying a default nameSpaceURI or documentType, these are optional
  436. *** We now have created the following XML:
  437. <root/>
  438. Next, you can either create a node in the document using the document element you created above
  439. var node1Element = rootElement.createElement("node1");
  440. OR you can create a element based on a namespace using the document element (rootElement in our case).
  441. var node1Element = XMLBuilderCreateElementNS("http://someNamespace", "node1", rootElement);
  442. Next, you can set attributes on the element
  443. node1Element.setAttribute("attrX", "valY");
  444. OR you can set namespaces on the element (or both of course)
  445. XMLBuilderSetAttributeNodeNS(node1Element, "xmlns:xs", "http://www.w3.org/2001/XMLSchema", "");
  446. --> Here we don't need to define the final parameter as it's part of the xmlns namespace.
  447. Note that if you declare a namespaces on the element which is not an "xmlns", you need to specify the namespace URI of that namespace.
  448. XMLBuilderSetAttributeNodeNS(node1Element, "xsi:type", "SOAP-ENC:Array", "http://www.w3.org/2001/XMLSchema-instance");
  449. --> In this case, since we uses "xsi", instead of "xmlns", we had to provide the final parameter.
  450. --> Note that when declaring the final parameter, you don't need to define "xsi" as an xmlns, it's included for free
  451. Next, you need to append the child node to the document node. Note that for children of the document element,
  452. you need to append as a child of the "documentElement", not the rootElement.
  453. rootElement.documentElement.appendChild(node1Element);
  454. For every other element you create (other than document elements) you can just use the following.
  455. node1Element.appendChild(node2Element);
  456. *** We now have created the following XML:
  457. <root>
  458. <node1 attrX="valY" xmlns:xs="http://www.w3.org/2001/XMLSchema"
  459. xmlns:xsi="http://www.w2.org/2001/XMLSchema-instance" xsi:type="SOAP-ENC:Array"/>
  460. </root>
  461. --> Note that the xmlns for xsi is automatically included for free.
  462. */