parser.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.xml.parser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.xml.parser"] = true;
  8. dojo.provide("dojox.xml.parser");
  9. //DOM type to int value for reference.
  10. //Ints make for more compact code than full constant names.
  11. //ELEMENT_NODE = 1;
  12. //ATTRIBUTE_NODE = 2;
  13. //TEXT_NODE = 3;
  14. //CDATA_SECTION_NODE = 4;
  15. //ENTITY_REFERENCE_NODE = 5;
  16. //ENTITY_NODE = 6;
  17. //PROCESSING_INSTRUCTION_NODE = 7;
  18. //COMMENT_NODE = 8;
  19. //DOCUMENT_NODE = 9;
  20. //DOCUMENT_TYPE_NODE = 10;
  21. //DOCUMENT_FRAGMENT_NODE = 11;
  22. //NOTATION_NODE = 12;
  23. dojox.xml.parser.parse = function(/*String?*/ str, /*String?*/ mimetype){
  24. // summary:
  25. // cross-browser implementation of creating an XML document object from null, empty string, and XML text..
  26. //
  27. // str:
  28. // Optional text to create the document from. If not provided, an empty XML document will be created.
  29. // If str is empty string "", then a new empty document will be created.
  30. // mimetype:
  31. // Optional mimetype of the text. Typically, this is text/xml. Will be defaulted to text/xml if not provided.
  32. var _document = dojo.doc;
  33. var doc;
  34. mimetype = mimetype || "text/xml";
  35. if(str && dojo.trim(str) && "DOMParser" in dojo.global){
  36. //Handle parsing the text on Mozilla based browsers etc..
  37. var parser = new DOMParser();
  38. doc = parser.parseFromString(str, mimetype);
  39. var de = doc.documentElement;
  40. var errorNS = "http://www.mozilla.org/newlayout/xml/parsererror.xml";
  41. if(de.nodeName == "parsererror" && de.namespaceURI == errorNS){
  42. var sourceText = de.getElementsByTagNameNS(errorNS, 'sourcetext')[0];
  43. if(sourceText){
  44. sourceText = sourceText.firstChild.data;
  45. }
  46. throw new Error("Error parsing text " + de.firstChild.data + " \n" + sourceText);
  47. }
  48. return doc;
  49. }else if("ActiveXObject" in dojo.global){
  50. //Handle IE.
  51. var ms = function(n){ return "MSXML" + n + ".DOMDocument"; };
  52. var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
  53. dojo.some(dp, function(p){
  54. try{
  55. doc = new ActiveXObject(p);
  56. }catch(e){ return false; }
  57. return true;
  58. });
  59. if(str && doc){
  60. doc.async = false;
  61. doc.loadXML(str);
  62. var pe = doc.parseError;
  63. if(pe.errorCode !== 0){
  64. throw new Error("Line: " + pe.line + "\n" +
  65. "Col: " + pe.linepos + "\n" +
  66. "Reason: " + pe.reason + "\n" +
  67. "Error Code: " + pe.errorCode + "\n" +
  68. "Source: " + pe.srcText);
  69. }
  70. }
  71. if(doc){
  72. return doc; //DOMDocument
  73. }
  74. }else if(_document.implementation && _document.implementation.createDocument){
  75. if(str && dojo.trim(str) && _document.createElement){
  76. //Everyone else that we couldn't get to work. Fallback case.
  77. // FIXME: this may change all tags to uppercase!
  78. var tmp = _document.createElement("xml");
  79. tmp.innerHTML = str;
  80. var xmlDoc = _document.implementation.createDocument("foo", "", null);
  81. dojo.forEach(tmp.childNodes, function(child){
  82. xmlDoc.importNode(child, true);
  83. });
  84. return xmlDoc; // DOMDocument
  85. }else{
  86. return _document.implementation.createDocument("", "", null); // DOMDocument
  87. }
  88. }
  89. return null; // null
  90. }
  91. dojox.xml.parser.textContent = function(/*Node*/node, /*String?*/text){
  92. // summary:
  93. // Implementation of the DOM Level 3 attribute; scan node for text
  94. // description:
  95. // Implementation of the DOM Level 3 attribute; scan node for text
  96. // This function can also update the text of a node by replacing all child
  97. // content of the node.
  98. // node:
  99. // The node to get the text off of or set the text on.
  100. // text:
  101. // Optional argument of the text to apply to the node.
  102. if(arguments.length>1){
  103. var _document = node.ownerDocument || dojo.doc; //Preference is to get the node owning doc first or it may fail
  104. dojox.xml.parser.replaceChildren(node, _document.createTextNode(text));
  105. return text; // String
  106. }else{
  107. if(node.textContent !== undefined){ //FF 1.5 -- remove?
  108. return node.textContent; // String
  109. }
  110. var _result = "";
  111. if(node){
  112. dojo.forEach(node.childNodes, function(child){
  113. switch(child.nodeType){
  114. case 1: // ELEMENT_NODE
  115. case 5: // ENTITY_REFERENCE_NODE
  116. _result += dojox.xml.parser.textContent(child);
  117. break;
  118. case 3: // TEXT_NODE
  119. case 2: // ATTRIBUTE_NODE
  120. case 4: // CDATA_SECTION_NODE
  121. _result += child.nodeValue;
  122. }
  123. });
  124. }
  125. return _result; // String
  126. }
  127. }
  128. dojox.xml.parser.replaceChildren = function(/*Element*/node, /*Node || Array*/ newChildren){
  129. // summary:
  130. // Removes all children of node and appends newChild. All the existing
  131. // children will be destroyed.
  132. // description:
  133. // Removes all children of node and appends newChild. All the existing
  134. // children will be destroyed.
  135. // node:
  136. // The node to modify the children on
  137. // newChildren:
  138. // The children to add to the node. It can either be a single Node or an
  139. // array of Nodes.
  140. var nodes = [];
  141. if(dojo.isIE){
  142. dojo.forEach(node.childNodes, function(child){
  143. nodes.push(child);
  144. });
  145. }
  146. dojox.xml.parser.removeChildren(node);
  147. dojo.forEach(nodes, dojo.destroy);
  148. if(!dojo.isArray(newChildren)){
  149. node.appendChild(newChildren);
  150. }else{
  151. dojo.forEach(newChildren, function(child){
  152. node.appendChild(child);
  153. });
  154. }
  155. }
  156. dojox.xml.parser.removeChildren = function(/*Element*/node){
  157. // summary:
  158. // removes all children from node and returns the count of children removed.
  159. // The children nodes are not destroyed. Be sure to call dojo.destroy on them
  160. // after they are not used anymore.
  161. // node:
  162. // The node to remove all the children from.
  163. var count = node.childNodes.length;
  164. while(node.hasChildNodes()){
  165. node.removeChild(node.firstChild);
  166. }
  167. return count; // int
  168. }
  169. dojox.xml.parser.innerXML = function(/*Node*/node){
  170. // summary:
  171. // Implementation of MS's innerXML function.
  172. // node:
  173. // The node from which to generate the XML text representation.
  174. if(node.innerXML){
  175. return node.innerXML; // String
  176. }else if(node.xml){
  177. return node.xml; // String
  178. }else if(typeof XMLSerializer != "undefined"){
  179. return (new XMLSerializer()).serializeToString(node); // String
  180. }
  181. return null;
  182. }
  183. }