if (!dojo._hasResource["dojox.wire.XmlWire"]) { // _hasResource checks added by // build. Do not use // _hasResource directly in your // code. dojo._hasResource["dojox.wire.XmlWire"] = true; dojo.provide("dojox.wire.XmlWire"); dojo.require("dojox.data.dom"); dojo.require("dojox.wire.Wire"); dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, { // summary: // A Wire for XML nodes or values (element, attribute and text) // description: // This class accesses XML nodes or value with a simplified // XPath // specified to 'path' property. // The root object for this class must be an DOM document or // element // node. // "@name" accesses to an attribute value of an element and // "text()" // accesses to a text value of an element. // The hierarchy of the elements from the root node can be // specified // with slash-separated list, such as "a/b/@c", which specifies // the value of an attribute named "c" of an element named "b" // as // a child of another element named "a" of a child of the root // node. _wireClass : "dojox.wire.XmlWire", constructor : function(/* Object */args) { // summary: // Initialize properties // description: // 'args' is just mixed in with no further processing. // args: // Arguments to initialize properties // path: // A simplified XPath to an attribute, a text or elements }, _getValue : function(/* Node */object) { // summary: // Return an attribute value, a text value or an array of // elements // description: // This method first uses a root node passed in 'object' // argument // and 'path' property to identify an attribute, a text or // elements. // If 'path' starts with a slash (absolute), the first path // segment is ignored assuming it point to the root node. // (That is, "/a/b/@c" and "b/@c" against a root node access // the same attribute value, assuming the root node is an // element // with a tag name, "a".) // object: // A root node // returns: // A value found, otherwise 'undefined' if (!object || !this.path) { return object; // Node } var node = object; var path = this.path; if (path.charAt(0) == '/') { // absolute // skip the first expression (supposed to select the top // node) var i = path.indexOf('/', 1); path = path.substring(i + 1); } var list = path.split('/'); var last = list.length - 1; for (var i = 0; i < last; i++) { node = this._getChildNode(node, list[i]); if (!node) { return undefined; // undefined } } var value = this._getNodeValue(node, list[last]); return value; // String||Array }, _setValue : function(/* Node */object, /* String */value) { // summary: // Set an attribute value or a child text value to an // element // description: // This method first uses a root node passed in 'object' // argument // and 'path' property to identify an attribute, a text or // elements. // If an intermediate element does not exist, it creates // an element of the tag name in the 'path' segment as a // child // node of the current node. // Finally, 'value' argument is set to an attribute or a // text // (a child node) of the leaf element. // object: // A root node // value: // A value to set if (!this.path) { return object; // Node } var node = object; var doc = this._getDocument(node); var path = this.path; if (path.charAt(0) == '/') { // absolute var i = path.indexOf('/', 1); if (!node) { var name = path.substring(1, i); node = doc.createElement(name); object = node; // to be returned as a new object } // skip the first expression (supposed to select the top // node) path = path.substring(i + 1); } else { if (!node) { return undefined; // undefined } } var list = path.split('/'); var last = list.length - 1; for (var i = 0; i < last; i++) { var child = this._getChildNode(node, list[i]); if (!child) { child = doc.createElement(list[i]); node.appendChild(child); } node = child; } this._setNodeValue(node, list[last], value); return object; // Node }, _getNodeValue : function(/* Node */node, /* String */exp) { // summary: // Return an attribute value, a text value or an array of // elements // description: // If 'exp' starts with '@', an attribute value of the // specified // attribute is returned. // If 'exp' is "text()", a child text value is returned. // Otherwise, an array of child elements, the tag name of // which // match 'exp', is returned. // node: // A node // exp: // An expression for attribute, text or elements // returns: // A value found, otherwise 'undefined' var value = undefined; if (exp.charAt(0) == '@') { var attribute = exp.substring(1); value = node.getAttribute(attribute); } else if (exp == "text()") { var text = node.firstChild; if (text) { value = text.nodeValue; } } else { // assume elements value = []; for (var i = 0; i < node.childNodes.length; i++) { var child = node.childNodes[i]; if (child.nodeType === 1 /* ELEMENT_NODE */ && child.nodeName == exp) { value.push(child); } } } return value; // String||Array }, _setNodeValue : function(/* Node */node, /* String */exp, /* String */ value) { // summary: // Set an attribute value or a child text value to an // element // description: // If 'exp' starts with '@', 'value' is set to the specified // attribute. // If 'exp' is "text()", 'value' is set to a child text. // node: // A node // exp: // An expression for attribute or text // value: // A value to set if (exp.charAt(0) == '@') { var attribute = exp.substring(1); if (value) { node.setAttribute(attribute, value); } else { node.removeAttribute(attribute); } } else if (exp == "text()") { while (node.firstChild) { node.removeChild(node.firstChild); } if (value) { var text = this._getDocument(node) .createTextNode(value); node.appendChild(text); } } // else not supported }, _getChildNode : function(/* Node */node, /* String */name) { // summary: // Return a child node // description: // A child element of the tag name specified with 'name' is // returned. // If 'name' ends with an array index, it is used to pick up // the corresponding element from multiple child elements. // node: // A parent node // name: // A tag name // returns: // A child node var index = 1; var i1 = name.indexOf('['); if (i1 >= 0) { var i2 = name.indexOf(']'); index = name.substring(i1 + 1, i2); name = name.substring(0, i1); } var count = 1; for (var i = 0; i < node.childNodes.length; i++) { var child = node.childNodes[i]; if (child.nodeType === 1 /* ELEMENT_NODE */ && child.nodeName == name) { if (count == index) { return child; // Node } count++; } } return null; // null }, _getDocument : function(/* Node */node) { // summary: // Return a DOM document // description: // If 'node' is specified, a DOM document of the node is // returned. // Otherwise, a DOM document is created. // returns: // A DOM document if (node) { return (node.nodeType == 9 /* DOCUMENT_NODE */ ? node : node.ownerDocument); // Document } else { return dojox.data.dom.createDocument(); // Document } } }); }