XmlWire.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // wrapped by build app
  2. define("dojox/wire/XmlWire", ["dijit","dojo","dojox","dojo/require!dojox/xml/parser,dojox/wire/Wire"], function(dijit,dojo,dojox){
  3. dojo.provide("dojox.wire.XmlWire");
  4. dojo.require("dojox.xml.parser");
  5. dojo.require("dojox.wire.Wire");
  6. dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
  7. // summary:
  8. // A Wire for XML nodes or values (element, attribute and text)
  9. // description:
  10. // This class accesses XML nodes or value with a simplified XPath
  11. // specified to 'path' property.
  12. // The root object for this class must be an DOM document or element
  13. // node.
  14. // "@name" accesses to an attribute value of an element and "text()"
  15. // accesses to a text value of an element.
  16. // The hierarchy of the elements from the root node can be specified
  17. // with slash-separated list, such as "a/b/@c", which specifies
  18. // the value of an attribute named "c" of an element named "b" as
  19. // a child of another element named "a" of a child of the root node.
  20. _wireClass: "dojox.wire.XmlWire",
  21. constructor: function(/*Object*/args){
  22. // summary:
  23. // Initialize properties
  24. // description:
  25. // 'args' is just mixed in with no further processing.
  26. // args:
  27. // Arguments to initialize properties
  28. // path:
  29. // A simplified XPath to an attribute, a text or elements
  30. },
  31. _getValue: function(/*Node*/object){
  32. // summary:
  33. // Return an attribute value, a text value or an array of elements
  34. // description:
  35. // This method first uses a root node passed in 'object' argument
  36. // and 'path' property to identify an attribute, a text or
  37. // elements.
  38. // If 'path' starts with a slash (absolute), the first path
  39. // segment is ignored assuming it point to the root node.
  40. // (That is, "/a/b/@c" and "b/@c" against a root node access
  41. // the same attribute value, assuming the root node is an element
  42. // with a tag name, "a".)
  43. // object:
  44. // A root node
  45. // returns:
  46. // A value found, otherwise 'undefined'
  47. if(!object || !this.path){
  48. return object; //Node
  49. }
  50. var node = object;
  51. var path = this.path;
  52. var i;
  53. if(path.charAt(0) == '/'){ // absolute
  54. // skip the first expression (supposed to select the top node)
  55. i = path.indexOf('/', 1);
  56. path = path.substring(i + 1);
  57. }
  58. var list = path.split('/');
  59. var last = list.length - 1;
  60. for(i = 0; i < last; i++){
  61. node = this._getChildNode(node, list[i]);
  62. if(!node){
  63. return undefined; //undefined
  64. }
  65. }
  66. var value = this._getNodeValue(node, list[last]);
  67. return value; //String||Array
  68. },
  69. _setValue: function(/*Node*/object, /*String*/value){
  70. // summary:
  71. // Set an attribute value or a child text value to an element
  72. // description:
  73. // This method first uses a root node passed in 'object' argument
  74. // and 'path' property to identify an attribute, a text or
  75. // elements.
  76. // If an intermediate element does not exist, it creates
  77. // an element of the tag name in the 'path' segment as a child
  78. // node of the current node.
  79. // Finally, 'value' argument is set to an attribute or a text
  80. // (a child node) of the leaf element.
  81. // object:
  82. // A root node
  83. // value:
  84. // A value to set
  85. if(!this.path){
  86. return object; //Node
  87. }
  88. var node = object;
  89. var doc = this._getDocument(node);
  90. var path = this.path;
  91. var i;
  92. if(path.charAt(0) == '/'){ // absolute
  93. i = path.indexOf('/', 1);
  94. if(!node){
  95. var name = path.substring(1, i);
  96. node = doc.createElement(name);
  97. object = node; // to be returned as a new object
  98. }
  99. // skip the first expression (supposed to select the top node)
  100. path = path.substring(i + 1);
  101. }else{
  102. if(!node){
  103. return undefined; //undefined
  104. }
  105. }
  106. var list = path.split('/');
  107. var last = list.length - 1;
  108. for(i = 0; i < last; i++){
  109. var child = this._getChildNode(node, list[i]);
  110. if(!child){
  111. child = doc.createElement(list[i]);
  112. node.appendChild(child);
  113. }
  114. node = child;
  115. }
  116. this._setNodeValue(node, list[last], value);
  117. return object; //Node
  118. },
  119. _getNodeValue: function(/*Node*/node, /*String*/exp){
  120. // summary:
  121. // Return an attribute value, a text value or an array of elements
  122. // description:
  123. // If 'exp' starts with '@', an attribute value of the specified
  124. // attribute is returned.
  125. // If 'exp' is "text()", a child text value is returned.
  126. // Otherwise, an array of child elements, the tag name of which
  127. // match 'exp', is returned.
  128. // node:
  129. // A node
  130. // exp:
  131. // An expression for attribute, text or elements
  132. // returns:
  133. // A value found, otherwise 'undefined'
  134. var value = undefined;
  135. if(exp.charAt(0) == '@'){
  136. var attribute = exp.substring(1);
  137. value = node.getAttribute(attribute);
  138. }else if(exp == "text()"){
  139. var text = node.firstChild;
  140. if(text){
  141. value = text.nodeValue;
  142. }
  143. }else{ // assume elements
  144. value = [];
  145. for(var i = 0; i < node.childNodes.length; i++){
  146. var child = node.childNodes[i];
  147. if(child.nodeType === 1 /* ELEMENT_NODE */ && child.nodeName == exp){
  148. value.push(child);
  149. }
  150. }
  151. }
  152. return value; //String||Array
  153. },
  154. _setNodeValue: function(/*Node*/node, /*String*/exp, /*String*/value){
  155. // summary:
  156. // Set an attribute value or a child text value to an element
  157. // description:
  158. // If 'exp' starts with '@', 'value' is set to the specified
  159. // attribute.
  160. // If 'exp' is "text()", 'value' is set to a child text.
  161. // node:
  162. // A node
  163. // exp:
  164. // An expression for attribute or text
  165. // value:
  166. // A value to set
  167. if(exp.charAt(0) == '@'){
  168. var attribute = exp.substring(1);
  169. if(value){
  170. node.setAttribute(attribute, value);
  171. }else{
  172. node.removeAttribute(attribute);
  173. }
  174. }else if(exp == "text()"){
  175. while(node.firstChild){
  176. node.removeChild(node.firstChild);
  177. }
  178. if(value){
  179. var text = this._getDocument(node).createTextNode(value);
  180. node.appendChild(text);
  181. }
  182. }
  183. // else not supported
  184. },
  185. _getChildNode: function(/*Node*/node, /*String*/name){
  186. // summary:
  187. // Return a child node
  188. // description:
  189. // A child element of the tag name specified with 'name' is
  190. // returned.
  191. // If 'name' ends with an array index, it is used to pick up
  192. // the corresponding element from multiple child elements.
  193. // node:
  194. // A parent node
  195. // name:
  196. // A tag name
  197. // returns:
  198. // A child node
  199. var index = 1;
  200. var i1 = name.indexOf('[');
  201. if(i1 >= 0){
  202. var i2 = name.indexOf(']');
  203. index = name.substring(i1 + 1, i2);
  204. name = name.substring(0, i1);
  205. }
  206. var count = 1;
  207. for(var i = 0; i < node.childNodes.length; i++){
  208. var child = node.childNodes[i];
  209. if(child.nodeType === 1 /* ELEMENT_NODE */ && child.nodeName == name){
  210. if(count == index){
  211. return child; //Node
  212. }
  213. count++;
  214. }
  215. }
  216. return null; //null
  217. },
  218. _getDocument: function(/*Node*/node){
  219. // summary:
  220. // Return a DOM document
  221. // description:
  222. // If 'node' is specified, a DOM document of the node is returned.
  223. // Otherwise, a DOM document is created.
  224. // returns:
  225. // A DOM document
  226. if(node){
  227. return (node.nodeType == 9 /* DOCUMENT_NODE */ ? node : node.ownerDocument); //Document
  228. }else{
  229. return dojox.xml.parser.parse(); //Document
  230. }
  231. }
  232. });
  233. });