]> git.pond.sub.org Git - eow/blobdiff - static/dojo-release-1.1.1/dojox/data/XmlStore.js
Replace Dojo with jQuery
[eow] / static / dojo-release-1.1.1 / dojox / data / XmlStore.js
diff --git a/static/dojo-release-1.1.1/dojox/data/XmlStore.js b/static/dojo-release-1.1.1/dojox/data/XmlStore.js
deleted file mode 100644 (file)
index 90b26a9..0000000
+++ /dev/null
@@ -1,1141 +0,0 @@
-if(!dojo._hasResource["dojox.data.XmlStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
-dojo._hasResource["dojox.data.XmlStore"] = true;
-dojo.provide("dojox.data.XmlStore");
-dojo.provide("dojox.data.XmlItem");
-
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.data.util.filter");
-dojo.require("dojox.data.dom");
-
-dojo.declare("dojox.data.XmlStore", null, {
-       //      summary:
-       //              A data store for XML based services or documents
-       //      description:
-       //              A data store for XML based services or documents
-       
-       constructor: function(/* object */ args) {
-               //      summary:
-               //              Constructor for the XML store.  
-               //      args:
-               //              An anonymous object to initialize properties.  It expects the following values:
-               //              url:            The url to a service or an XML document that represents the store
-               //              rootItem:       A tag name for root items
-               //              keyAttribute:   An attribute name for a key or an indentify
-               //              attributeMap:   An anonymous object contains properties for attribute mapping,
-               //                                              {"tag_name.item_attribute_name": "@xml_attribute_name", ...}
-               //              sendQuery:              A boolean indicate to add a query string to the service URL 
-               console.log("XmlStore()");
-               if(args){
-                       this.url = args.url;
-                       this.rootItem = (args.rootItem || args.rootitem || this.rootItem);
-                       this.keyAttribute = (args.keyAttribute || args.keyattribute || this.keyAttribute);
-                       this._attributeMap = (args.attributeMap || args.attributemap);
-                       this.label = args.label || this.label;
-                       this.sendQuery = (args.sendQuery || args.sendquery || this.sendQuery);
-               }
-               this._newItems = [];
-               this._deletedItems = [];
-               this._modifiedItems = [];
-       },
-
-       //Values that may be set by the parser.  
-       //Ergo, have to be instantiated to something
-       //So the parser knows how to set them.
-       url: "",
-
-       rootItem: "",
-
-       keyAttribute: "",
-
-       label: "",
-
-       sendQuery: false,
-
-/* dojo.data.api.Read */
-
-       getValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* value? */ defaultValue){
-               //      summary:
-               //              Return an attribute value
-               //      description:
-               //              'item' must be an instance of a dojox.data.XmlItem from the store instance.
-               //              If 'attribute' specifies "tagName", the tag name of the element is
-               //              returned.
-               //              If 'attribute' specifies "childNodes", the first element child is
-               //              returned.
-               //              If 'attribute' specifies "text()", the value of the first text
-               //              child is returned.
-               //              For generic attributes, if '_attributeMap' is specified,
-               //              an actual attribute name is looked up with the tag name of
-               //              the element and 'attribute' (concatenated with '.').
-               //              Then, if 'attribute' starts with "@", the value of the XML
-               //              attribute is returned.
-               //              Otherwise, the first child element of the tag name specified with
-               //              'attribute' is returned.
-               //      item:
-               //              An XML element that holds the attribute
-               //      attribute:
-               //              A tag name of a child element, An XML attribute name or one of
-               //              special names
-               //      defaultValue:
-               //              A default value
-               //      returns:
-               //              An attribute value found, otherwise 'defaultValue'
-               var element = item.element;
-               if(attribute === "tagName"){
-                       return element.nodeName;
-               }else if (attribute === "childNodes"){
-                       for (var i = 0; i < element.childNodes.length; i++) {
-                               var node = element.childNodes[i];
-                               if (node.nodeType === 1 /*ELEMENT_NODE*/) {
-                                       return this._getItem(node); //object
-                               }
-                       }
-                       return defaultValue;
-               }else if(attribute === "text()"){
-                       for(var i = 0; i < element.childNodes.length; i++){
-                               var node = element.childNodes[i];
-                               if(node.nodeType === 3 /*TEXT_NODE*/ ||
-                                       node.nodeType === 4 /*CDATA_SECTION_NODE*/){
-                                       return node.nodeValue; //string
-                               }
-                       }
-                       return defaultValue;
-               }else{
-                       attribute = this._getAttribute(element.nodeName, attribute);
-                       if(attribute.charAt(0) === '@'){
-                               var name = attribute.substring(1);
-                               var value = element.getAttribute(name);
-                               return (value !== undefined) ? value : defaultValue; //object
-                       }else{
-                               for(var i = 0; i < element.childNodes.length; i++){
-                                       var node = element.childNodes[i];
-                                       if(     node.nodeType === 1 /*ELEMENT_NODE*/ &&
-                                               node.nodeName === attribute){
-                                               return this._getItem(node); //object
-                                       }
-                               }
-                               return defaultValue; //object
-                       }
-               }
-       },
-
-       getValues: function(/* item */ item, /* attribute || attribute-name-string */ attribute){
-               //      summary:
-               //              Return an array of attribute values
-               //      description:
-               //              'item' must be an instance of a dojox.data.XmlItem from the store instance.
-               //              If 'attribute' specifies "tagName", the tag name of the element is
-               //              returned.
-               //              If 'attribute' specifies "childNodes", child elements are returned.
-               //              If 'attribute' specifies "text()", the values of child text nodes
-               //              are returned.
-               //              For generic attributes, if '_attributeMap' is specified,
-               //              an actual attribute name is looked up with the tag name of
-               //              the element and 'attribute' (concatenated with '.').
-               //              Then, if 'attribute' starts with "@", the value of the XML
-               //              attribute is returned.
-               //              Otherwise, child elements of the tag name specified with
-               //              'attribute' are returned.
-               //      item:
-               //              An XML element that holds the attribute
-               //      attribute:
-               //              A tag name of child elements, An XML attribute name or one of
-               //              special names
-               //      returns:
-               //              An array of attribute values found, otherwise an empty array
-               var element = item.element;
-               if(attribute === "tagName"){
-                       return [element.nodeName];
-               }else if(attribute === "childNodes"){
-                       var values = [];
-                       for(var i = 0; i < element.childNodes.length; i++){
-                               var node = element.childNodes[i];
-                               if(node.nodeType === 1 /*ELEMENT_NODE*/){
-                                       values.push(this._getItem(node));
-                               }
-                       }
-                       return values; //array
-               }else if(attribute === "text()"){
-                       var values = [];
-                       for(var i = 0; i < element.childNodes.length; i++){
-                               var node = childNodes[i];
-                               if(node.nodeType === 3){
-                                       values.push(node.nodeValue);
-                               }
-                       }
-                       return values; //array
-               }else{
-                       attribute = this._getAttribute(element.nodeName, attribute);
-                       if(attribute.charAt(0) === '@'){
-                               var name = attribute.substring(1);
-                               var value = element.getAttribute(name);
-                               return (value !== undefined) ? [value] : []; //array
-                       }else{
-                               var values = [];
-                               for(var i = 0; i < element.childNodes.length; i++){
-                                       var node = element.childNodes[i];
-                                       if(     node.nodeType === 1 /*ELEMENT_NODE*/ &&
-                                               node.nodeName === attribute){
-                                               values.push(this._getItem(node));
-                                       }
-                               }
-                               return values; //array
-                       }
-               }
-       },
-
-       getAttributes: function(/* item */ item) {
-               //      summary:
-               //              Return an array of attribute names
-               //      description:
-               //              'item' must be an instance of a dojox.data.XmlItem from the store instance.
-               //              tag names of child elements and XML attribute names of attributes
-               //              specified to the element are returned along with special attribute
-               //              names applicable to the element including "tagName", "childNodes"
-               //              if the element has child elements, "text()" if the element has
-               //              child text nodes, and attribute names in '_attributeMap' that match
-               //              the tag name of the element.
-               //      item:
-               //              An XML element
-               //      returns:
-               //              An array of attributes found
-               var element = item.element;
-               var attributes = [];
-               attributes.push("tagName");
-               if(element.childNodes.length > 0){
-                       var names = {};
-                       var childNodes = true;
-                       var text = false;
-                       for(var i = 0; i < element.childNodes.length; i++){
-                               var node = element.childNodes[i];
-                               if (node.nodeType === 1 /*ELEMENT_NODE*/) {
-                                       var name = node.nodeName;
-                                       if(!names[name]){
-                                               attributes.push(name);
-                                               names[name] = name;
-                                       }
-                                       childNodes = true;
-                               }else if(node.nodeType === 3){
-                                       text = true;
-                               }
-                       }
-                       if(childNodes){
-                               attributes.push("childNodes");
-                       }
-                       if(text){
-                               attributes.push("text()");
-                       }
-               }
-               for(var i = 0; i < element.attributes.length; i++){
-                       attributes.push("@" + element.attributes[i].nodeName);
-               }
-               if(this._attributeMap){
-                       for (var key in this._attributeMap){
-                               var i = key.indexOf('.');
-                               if(i > 0){
-                                       var tagName = key.substring(0, i);
-                                       if (tagName === element.nodeName){
-                                               attributes.push(key.substring(i + 1));
-                                       }
-                               }else{ // global attribute
-                                       attributes.push(key);
-                               }
-                       }
-               }
-               return attributes; //array
-       },
-
-       hasAttribute: function(/* item */ item, /* attribute || attribute-name-string */ attribute){
-               //      summary:
-               //              Check whether an element has the attribute
-               //      item:
-               //              'item' must be an instance of a dojox.data.XmlItem from the store instance.
-               //      attribute:
-               //              A tag name of a child element, An XML attribute name or one of
-               //              special names
-               //      returns:
-               //              True if the element has the attribute, otherwise false
-               return (this.getValue(item, attribute) !== undefined); //boolean
-       },
-
-       containsValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* anything */ value){
-               //      summary:
-               //              Check whether the attribute values contain the value
-               //      item:
-               //              'item' must be an instance of a dojox.data.XmlItem from the store instance.
-               //      attribute:
-               //              A tag name of a child element, An XML attribute name or one of
-               //              special names
-               //      returns:
-               //              True if the attribute values contain the value, otherwise false
-               var values = this.getValues(item, attribute);
-               for(var i = 0; i < values.length; i++){
-                       if((typeof value === "string")){
-                               if(values[i].toString && values[i].toString() === value){
-                                       return true;
-                               }
-                       }else if (values[i] === value){
-                               return true; //boolean
-                       }
-               }
-               return false;//boolean
-       },
-
-       isItem: function(/* anything */ something){
-               //      summary:
-               //              Check whether the object is an item (XML element)
-               //      item:
-               //              An object to check
-               //      returns:
-               //              True if the object is an XML element, otherwise false
-               if(something && something.element && something.store && something.store === this){
-                       return true; //boolean
-               }
-               return false; //boolran
-       },
-
-       isItemLoaded: function(/* anything */ something){
-               //      summary:
-               //              Check whether the object is an item (XML element) and loaded
-               //      item:
-               //              An object to check
-               //      returns:
-               //              True if the object is an XML element, otherwise false
-               return this.isItem(something); //boolean
-       },
-
-       loadItem: function(/* object */ keywordArgs){
-               //      summary:
-               //              Load an item (XML element)
-               //      keywordArgs:
-               //              object containing the args for loadItem.  See dojo.data.api.Read.loadItem()
-       },
-
-       getFeatures: function() {
-               //      summary:
-               //              Return supported data APIs
-               //      returns:
-               //              "dojo.data.api.Read" and "dojo.data.api.Write"
-               var features = {
-                       "dojo.data.api.Read": true,
-                       "dojo.data.api.Write": true
-               };
-               return features; //array
-       },
-
-       getLabel: function(/* item */ item){
-               //      summary: 
-               //              See dojo.data.api.Read.getLabel()
-               if((this.label !== "") && this.isItem(item)){
-                       var label = this.getValue(item,this.label);
-                       if(label){
-                               return label.toString();
-                       }
-               }
-               return undefined; //undefined
-       },
-
-       getLabelAttributes: function(/* item */ item){
-               //      summary: 
-               //              See dojo.data.api.Read.getLabelAttributes()
-               if(this.label !== ""){
-                       return [this.label]; //array
-               }
-               return null; //null
-       },
-
-       _fetchItems: function(request, fetchHandler, errorHandler) {
-               //      summary:
-               //              Fetch items (XML elements) that match to a query
-               //      description:
-               //              If 'sendQuery' is true, an XML document is loaded from
-               //              'url' with a query string.
-               //              Otherwise, an XML document is loaded and list XML elements that
-               //              match to a query (set of element names and their text attribute
-               //              values that the items to contain).
-               //              A wildcard, "*" can be used to query values to match all
-               //              occurrences.
-               //              If 'rootItem' is specified, it is used to fetch items.
-               //      request:
-               //              A request object
-               //      fetchHandler:
-               //              A function to call for fetched items
-               //      errorHandler:
-               //              A function to call on error
-               var url = this._getFetchUrl(request);
-               console.log("XmlStore._fetchItems(): url=" + url);
-               if(!url){
-                       errorHandler(new Error("No URL specified."));
-                       return;
-               }
-               var localRequest = (!this.sendQuery ? request : null); // use request for _getItems()
-
-               var self = this;
-               var getArgs = {
-                               url: url,
-                               handleAs: "xml",
-                               preventCache: true
-                       };
-               var getHandler = dojo.xhrGet(getArgs);
-               getHandler.addCallback(function(data){
-                       var items = self._getItems(data, localRequest);
-                       console.log("XmlStore._fetchItems(): length=" + (items ? items.length : 0));
-                       if (items && items.length > 0) {
-                               fetchHandler(items, request);
-                       }
-                       else {
-                               fetchHandler([], request);
-                       }
-               });
-               getHandler.addErrback(function(data){
-                       errorHandler(data, request);
-               });
-       },
-
-       _getFetchUrl: function(request){
-               //      summary:
-               //              Generate a URL for fetch
-               //      description:
-               //              This default implementation generates a query string in the form of
-               //              "?name1=value1&name2=value2..." off properties of 'query' object
-               //              specified in 'request' and appends it to 'url', if 'sendQuery'
-               //              is set to false.
-               //              Otherwise, 'url' is returned as is.
-               //              Sub-classes may override this method for the custom URL generation.
-               //      request:
-               //              A request object
-               //      returns:
-               //              A fetch URL
-               if(!this.sendQuery){
-                       return this.url;
-               }
-               var query = request.query;
-               if(!query){
-                       return this.url;
-               }
-               if(dojo.isString(query)){
-                       return this.url + query;
-               }
-               var queryString = "";
-               for(var name in query){
-                       var value = query[name];
-                       if(value){
-                               if(queryString){
-                                       queryString += "&";
-                               }
-                               queryString += (name + "=" + value);
-                       }
-               }
-               if(!queryString){
-                       return this.url;
-               }
-               //Check to see if the URL already has query params or not.
-               var fullUrl = this.url;
-               if(fullUrl.indexOf("?") < 0){
-                       fullUrl += "?";
-               }else{
-                       fullUrl += "&";
-               }
-               return fullUrl + queryString;
-       },
-
-       _getItems: function(document, request) {
-               //      summary:
-               //              Fetch items (XML elements) in an XML document based on a request
-               //      description:
-               //              This default implementation walks through child elements of
-               //              the document element to see if all properties of 'query' object
-               //              match corresponding attributes of the element (item).
-               //              If 'request' is not specified, all child elements are returned.
-               //              Sub-classes may override this method for the custom search in
-               //              an XML document.
-               //      document:
-               //              An XML document
-               //      request:
-               //              A request object
-               //      returns:
-               //              An array of items
-               var query = null;
-               if(request){
-                       query = request.query;
-               }
-               var items = [];
-               var nodes = null;
-
-               console.log("Looking up root item: " + this.rootItem);
-               if(this.rootItem !== ""){
-                       
-                       nodes = document.getElementsByTagName(this.rootItem);
-               }
-               else{
-                       nodes = document.documentElement.childNodes;
-               }
-               for(var i = 0; i < nodes.length; i++){
-                       var node = nodes[i];
-                       if(node.nodeType != 1 /*ELEMENT_NODE*/){
-                               continue;
-                       }
-            var item = this._getItem(node);
-                       if(query){
-                               var found = true;
-                               var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false; 
-
-                               //See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
-                               //same value for each item examined.  Much more efficient.
-                               var regexpList = {};
-                               for(var key in query){
-                                       var value = query[key];
-                                       if(typeof value === "string"){
-                                               regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
-                                       }
-                               }
-
-                               for(var attribute in query){
-                                       var value = this.getValue(item, attribute);
-                                       if(value){
-                                               var queryValue = query[attribute];
-                                               if ((typeof value) === "string" && 
-                                                       (regexpList[attribute])){
-                                                       if((value.match(regexpList[attribute])) !== null){
-                                                               continue;
-                                                       }
-                                               }else if((typeof value) === "object"){
-                                                       if(     value.toString && 
-                                                               (regexpList[attribute])){
-                                                               var stringValue = value.toString();
-                                                               if((stringValue.match(regexpList[attribute])) !== null){
-                                                                       continue;
-                                                               }
-                                                       }else{
-                                                               if(queryValue === "*" || queryValue === value){
-                                                                       continue;
-                                                               }
-                                                       }
-                                               }
-                                       }
-                                       found = false;
-                                       break;
-                               }
-                               if(!found){
-                                       continue;
-                               }
-                       }
-                       items.push(item);
-               }
-               dojo.forEach(items,function(item){ 
-                       item.element.parentNode.removeChild(item.element); // make it root
-               },this); 
-               return items;
-       },
-
-       close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-                //     summary: 
-                //             See dojo.data.api.Read.close()
-       },
-
-/* dojo.data.api.Write */
-
-       newItem: function(/* object? */ keywordArgs){
-               //      summary:
-               //              Return a new dojox.data.XmlItem
-               //      description:
-               //              At least, 'keywordArgs' must contain "tagName" to be used for
-               //              the new element.
-               //              Other attributes in 'keywordArgs' are set to the new element,
-               //              including "text()", but excluding "childNodes".
-               //      keywordArgs:
-               //              An object containing initial attributes
-               //      returns:
-               //              An XML element
-               console.log("XmlStore.newItem()");
-               keywordArgs = (keywordArgs || {});
-               var tagName = keywordArgs.tagName;
-               if(!tagName){
-                       tagName = this.rootItem;
-                       if(tagName === ""){
-                               return null;
-                       }
-               }
-
-               var document = this._getDocument();
-               var element = document.createElement(tagName);
-               for(var attribute in keywordArgs){
-                       if(attribute === "tagName"){
-                               continue;
-                       }else if(attribute === "text()"){
-                               var text = document.createTextNode(keywordArgs[attribute]);
-                               element.appendChild(text);
-                       }else{
-                               attribute = this._getAttribute(tagName, attribute);
-                               if(attribute.charAt(0) === '@'){
-                                       var name = attribute.substring(1);
-                                       element.setAttribute(name, keywordArgs[attribute]);
-                               }else{
-                                       var child = document.createElement(attribute);
-                                       var text = document.createTextNode(keywordArgs[attribute]);
-                                       child.appendChild(text);
-                                       element.appendChild(child);
-                               }
-                       }
-               }
-
-               var item = this._getItem(element);
-               this._newItems.push(item);
-               return item; //object
-       },
-       
-       deleteItem: function(/* item */ item){
-               //      summary:
-               //              Delete an dojox.data.XmlItem (wrapper to a XML element).
-               //      item:
-               //              An XML element to delete
-               //      returns:
-               //              True
-               console.log("XmlStore.deleteItem()");
-               var element = item.element;
-               if(element.parentNode){
-                       this._backupItem(item);
-                       element.parentNode.removeChild(element);
-                       return true;
-               }
-               this._forgetItem(item);
-               this._deletedItems.push(item);
-               return true; //boolean
-       },
-       
-       setValue: function(/* item */ item, /* attribute || string */ attribute, /* almost anything */ value){
-               //      summary:
-               //              Set an attribute value
-               //      description:
-               //              'item' must be an instance of a dojox.data.XmlItem from the store instance.
-               //              If 'attribute' specifies "tagName", nothing is set and false is
-               //              returned.
-               //              If 'attribute' specifies "childNodes", the value (XML element) is
-               //              added to the element.
-               //              If 'attribute' specifies "text()", a text node is created with
-               //              the value and set it to the element as a child.
-               //              For generic attributes, if '_attributeMap' is specified,
-               //              an actual attribute name is looked up with the tag name of
-               //              the element and 'attribute' (concatenated with '.').
-               //              Then, if 'attribute' starts with "@", the value is set to the XML
-               //              attribute.
-               //              Otherwise, a text node is created with the value and set it to
-               //              the first child element of the tag name specified with 'attribute'.
-               //              If the child element does not exist, it is created.
-               //      item:
-               //              An XML element that holds the attribute
-               //      attribute:
-               //              A tag name of a child element, An XML attribute name or one of
-               //              special names
-               //      value:
-               //              A attribute value to set
-               //      returns:
-               //              False for "tagName", otherwise true
-               if(attribute === "tagName"){
-                       return false; //boolean
-               }
-
-               this._backupItem(item);
-
-               var element = item.element;
-               if(attribute === "childNodes"){
-                       var child = value.element;
-                       element.appendChild(child);
-               }else if(attribute === "text()"){
-                       while (element.firstChild){
-                               element.removeChild(element.firstChild);
-                       }
-                       var text = this._getDocument(element).createTextNode(value);
-                       element.appendChild(text);
-               }else{
-                       attribute = this._getAttribute(element.nodeName, attribute);
-                       if(attribute.charAt(0) === '@'){
-                               var name = attribute.substring(1);
-                               element.setAttribute(name, value);
-                       }else{
-                               var child = null;
-                               for(var i = 0; i < element.childNodes.length; i++){
-                                       var node = element.childNodes[i];
-                                       if(     node.nodeType === 1 /*ELEMENT_NODE*/&&
-                                               node.nodeName === attribute){
-                                               child = node;
-                                               break;
-                                       }
-                               }
-                               var document = this._getDocument(element);
-                               if(child){
-                                       while(child.firstChild){
-                                               child.removeChild(child.firstChild);
-                                       }
-                               }else{
-                                       child = document.createElement(attribute);
-                                       element.appendChild(child);
-                               }
-                               var text = document.createTextNode(value);
-                               child.appendChild(text);
-                       }
-               }
-               return true; //boolean
-       },
-       
-       setValues: function(/* item */ item, /* attribute || string */ attribute, /* array */ values){
-               //      summary:
-               //              Set attribute values
-               //      description:
-               //              'item' must be an instance of a dojox.data.XmlItem from the store instance.
-               //              If 'attribute' specifies "tagName", nothing is set and false is
-               //              returned.
-               //              If 'attribute' specifies "childNodes", the value (array of XML
-               //              elements) is set to the element's childNodes.
-               //              If 'attribute' specifies "text()", a text node is created with
-               //              the values and set it to the element as a child.
-               //              For generic attributes, if '_attributeMap' is specified,
-               //              an actual attribute name is looked up with the tag name of
-               //              the element and 'attribute' (concatenated with '.').
-               //              Then, if 'attribute' starts with "@", the first value is set to
-               //              the XML attribute.
-               //              Otherwise, child elements of the tag name specified with
-               //              'attribute' are replaced with new child elements and their
-               //              child text nodes of values.
-               //      item:
-               //              An XML element that holds the attribute
-               //      attribute:
-               //              A tag name of child elements, an XML attribute name or one of
-               //              special names
-               //      value:
-               //              A attribute value to set
-               //      returns:
-               //              False for "tagName", otherwise true
-               if(attribute === "tagName"){
-                       return false; //boolean
-               }
-
-               this._backupItem(item);
-
-               var element = item.element;
-               if(attribute === "childNodes"){
-                       while(element.firstChild){
-                               element.removeChild(element.firstChild);
-                       }
-                       for(var i = 0; i < values.length; i++){
-                               var child = values[i].element;
-                               element.appendChild(child);
-                       }
-               }else if(attribute === "text()"){
-                       while (element.firstChild){
-                               element.removeChild(element.firstChild);
-                       }
-                       var value = "";
-                       for(var i = 0; i < values.length; i++){
-                               value += values[i];
-                       }
-                       var text = this._getDocument(element).createTextNode(value);
-                       element.appendChild(text);
-               }else{
-                       attribute = this._getAttribute(element.nodeName, attribute);
-                       if(attribute.charAt(0) === '@'){
-                               var name = attribute.substring(1);
-                               element.setAttribute(name, values[0]);
-                       }else{
-                               for(var i = element.childNodes.length - 1; i >= 0; i--){
-                                       var node = element.childNodes[i];
-                                       if(     node.nodeType === 1 /*ELEMENT_NODE*/ &&
-                                               node.nodeName === attribute){
-                                               element.removeChild(node);
-                                       }
-                               }
-                               var document = this._getDocument(element);
-                               for(var i = 0; i < values.length; i++){
-                                       var child = document.createElement(attribute);
-                                       var text = document.createTextNode(values[i]);
-                                       child.appendChild(text);
-                                       element.appendChild(child);
-                               }
-                       }
-               }
-               return true; //boolean
-       },
-       
-       unsetAttribute: function(/* item */ item, /* attribute || string */ attribute){
-               //      summary:
-               //              Remove an attribute
-               //      description:
-               //              'item' must be an instance of a dojox.data.XmlItem from the store instance.
-               //              'attribute' can be an XML attribute name of the element or one of
-               //              special names described below.
-               //              If 'attribute' specifies "tagName", nothing is removed and false is
-               //              returned.
-               //              If 'attribute' specifies "childNodes" or "text()", all child nodes
-               //              are removed.
-               //              For generic attributes, if '_attributeMap' is specified,
-               //              an actual attribute name is looked up with the tag name of
-               //              the element and 'attribute' (concatenated with '.').
-               //              Then, if 'attribute' starts with "@", the XML attribute is removed.
-               //              Otherwise, child elements of the tag name specified with
-               //              'attribute' are removed.
-               //      item:
-               //              An XML element that holds the attribute
-               //      attribute:
-               //              A tag name of child elements, an XML attribute name or one of
-               //              special names
-               //      returns:
-               //              False for "tagName", otherwise true
-               if(attribute === "tagName"){
-                       return false; //boolean
-               }
-
-               this._backupItem(item);
-
-               var element = item.element;
-               if(attribute === "childNodes" || attribute === "text()"){
-                       while(element.firstChild){
-                               element.removeChild(element.firstChild);
-                       }
-               }else{
-                       attribute = this._getAttribute(element.nodeName, attribute);
-                       if(attribute.charAt(0) === '@'){
-                               var name = attribute.substring(1);
-                               element.removeAttribute(name);
-                       }else{
-                               for(var i = element.childNodes.length - 1; i >= 0; i--){
-                                       var node = element.childNodes[i];
-                                       if(     node.nodeType === 1 /*ELEMENT_NODE*/ &&
-                                               node.nodeName === attribute){
-                                               element.removeChild(node);
-                                       }
-                               }
-                       }
-               }
-               return true; //boolean
-       },
-       
-       save: function(/* object */ keywordArgs){
-               //      summary:
-               //              Save new and/or modified items (XML elements)
-               //      description:
-               //              'url' is used to save XML documents for new, modified and/or
-               //              deleted XML elements.
-               //      keywordArgs:
-               //              An object for callbacks
-               if(!keywordArgs){
-                       keywordArgs = {};
-               }
-               for(var i = 0; i < this._modifiedItems.length; i++){
-                       this._saveItem(this._modifiedItems[i], keywordArgs, "PUT");
-               }
-               for(var i = 0; i < this._newItems.length; i++){
-                       var item = this._newItems[i];
-                       if(item.element.parentNode){ // reparented
-                               this._newItems.splice(i, 1);
-                               i--;
-                               continue;
-                       }
-                       this._saveItem(this._newItems[i], keywordArgs, "POST");
-               }
-               for(var i = 0; i < this._deletedItems.length; i++){
-                       this._saveItem(this._deletedItems[i], keywordArgs, "DELETE");
-               }
-       },
-
-       revert: function(){
-               // summary:
-               //      Invalidate changes (new and/or modified elements)
-               // returns:
-               //      True
-               console.log("XmlStore.revert() _newItems=" + this._newItems.length);
-               console.log("XmlStore.revert() _deletedItems=" + this._deletedItems.length);
-               console.log("XmlStore.revert() _modifiedItems=" + this._modifiedItems.length);
-               this._newItems = [];
-               this._restoreItems(this._deletedItems);
-               this._deletedItems = [];
-               this._restoreItems(this._modifiedItems);
-               this._modifiedItems = [];
-               return true; //boolean
-       },
-       
-       isDirty: function(/* item? */ item){
-               //      summary:
-               //              Check whether an item is new, modified or deleted
-               //      description:
-               //              If 'item' is specified, true is returned if the item is new,
-               //              modified or deleted.
-               //              Otherwise, true is returned if there are any new, modified
-               //              or deleted items.
-               //      item:
-               //              An item (XML element) to check
-               //      returns:
-               //              True if an item or items are new, modified or deleted, otherwise
-               //              false
-               if (item) {
-                       var element = this._getRootElement(item.element);
-                       return (this._getItemIndex(this._newItems, element) >= 0 ||
-                               this._getItemIndex(this._deletedItems, element) >= 0 ||
-                               this._getItemIndex(this._modifiedItems, element) >= 0); //boolean
-               }
-               else {
-                       return (this._newItems.length > 0 ||
-                               this._deletedItems.length > 0 ||
-                               this._modifiedItems.length > 0); //boolean
-               }
-       },
-
-       _saveItem: function(item, keywordArgs, method){
-               if(method === "PUT"){
-                       url = this._getPutUrl(item);
-               }else if(method === "DELETE"){
-                       url = this._getDeleteUrl(item);
-               }else{ // POST
-                       url = this._getPostUrl(item);
-               }
-               if(!url){
-                       if(keywordArgs.onError){
-                               keywordArgs.onError.call(scope, new Error("No URL for saving content: " + postContent));
-                       }
-                       return;
-               }
-
-               var saveArgs = {
-                       url: url,
-                       method: (method || "POST"),
-                       contentType: "text/xml",
-                       handleAs: "xml"
-               };
-               var saveHander;
-               if(method === "PUT"){
-                       saveArgs.putData = this._getPutContent(item);
-                       saveHandler = dojo.rawXhrPut(saveArgs);
-               }else if(method === "DELETE"){
-                       saveHandler = dojo.xhrDelete(saveArgs);
-               }else{ // POST
-                       saveArgs.postData = this._getPostContent(item);
-                       saveHandler = dojo.rawXhrPost(saveArgs);
-               }
-               var scope = (keywordArgs.scope || dojo.global);
-               var self = this;
-               saveHandler.addCallback(function(data){
-                       self._forgetItem(item);
-                       if(keywordArgs.onComplete){
-                               keywordArgs.onComplete.call(scope);
-                       }
-               });
-               saveHandler.addErrback(function(error){
-                       if(keywordArgs.onError){
-                               keywordArgs.onError.call(scope, error);
-                       }
-               });
-       },
-
-       _getPostUrl: function(item){
-               //      summary:
-               //              Generate a URL for post
-               //      description:
-               //              This default implementation just returns 'url'.
-               //              Sub-classes may override this method for the custom URL.
-               //      item:
-               //              An item to save
-               //      returns:
-               //              A post URL
-               return this.url; //string
-       },
-
-       _getPutUrl: function(item){
-               //      summary:
-               //              Generate a URL for put
-               //      description:
-               //              This default implementation just returns 'url'.
-               //              Sub-classes may override this method for the custom URL.
-               //      item:
-               //              An item to save
-               //      returns:
-               //              A put URL
-               return this.url; //string
-       },
-
-       _getDeleteUrl: function(item){
-               //      summary:
-               //              Generate a URL for delete
-               //      description:
-               //              This default implementation returns 'url' with 'keyAttribute'
-               //              as a query string.
-               //              Sub-classes may override this method for the custom URL based on
-               //              changes (new, deleted, or modified).
-               //      item:
-               //              An item to delete
-               //      returns:
-               //              A delete URL
-               var url = this.url;
-               if (item && this.keyAttribute !== "") {
-                       var value = this.getValue(item, this.keyAttribute);
-                       if (value) {
-                               var key = this.keyAttribute.charAt(0) ==='@' ? this.keyAttribute.substring(1): this.keyAttribute;
-                               url += url.indexOf('?') < 0 ? '?' : '&';
-                               url += key + '=' + value;
-                       }
-               }
-               return url;     //string
-       },
-
-       _getPostContent: function(item){
-               //      summary:
-               //              Generate a content to post
-               //      description:
-               //              This default implementation generates an XML document for one
-               //              (the first only) new or modified element.
-               //              Sub-classes may override this method for the custom post content
-               //              generation.
-               //      item:
-               //              An item to save
-               //      returns:
-               //              A post content
-               var element = item.element;
-               var declaration = "<?xml version=\"1.0\"?>"; // FIXME: encoding?
-               return declaration + dojox.data.dom.innerXML(element); //XML string
-       },
-
-       _getPutContent: function(item){
-               //      summary:
-               //              Generate a content to put
-               //      description:
-               //              This default implementation generates an XML document for one
-               //              (the first only) new or modified element.
-               //              Sub-classes may override this method for the custom put content
-               //              generation.
-               //      item:
-               //              An item to save
-               //      returns:
-               //              A post content
-               var element = item.element;
-               var declaration = "<?xml version=\"1.0\"?>"; // FIXME: encoding?
-               return declaration + dojox.data.dom.innerXML(element); //XML string
-       },
-
-/* internal API */
-
-       _getAttribute: function(tagName, attribute){
-               if(this._attributeMap){
-                       var key = tagName + "." + attribute;
-                       var value = this._attributeMap[key];
-                       if(value){
-                               attribute = value;
-                       }else{ // look for global attribute
-                               value = this._attributeMap[attribute];
-                               if(value){
-                                       attribute = value;
-                               }
-                       }
-               }
-               return attribute; //object
-       },
-
-       _getItem: function(element){
-               return new dojox.data.XmlItem(element, this); //object
-       },
-
-       _getItemIndex: function(items, element){
-               for(var i = 0; i < items.length; i++){
-                       if(items[i].element === element){
-                               return i; //int
-                       }
-               }
-               return -1; //int
-       },
-
-       _backupItem: function(item){
-               var element = this._getRootElement(item.element);
-               if(     this._getItemIndex(this._newItems, element) >= 0 ||
-                       this._getItemIndex(this._modifiedItems, element) >= 0){
-                       return; // new or already modified
-               }
-               if(element != item.element){
-                       item = this._getItem(element);
-               }
-               item._backup = element.cloneNode(true);
-               this._modifiedItems.push(item);
-       },
-
-       _restoreItems: function(items){
-
-               dojo.forEach(items,function(item){ 
-                       if(item._backup){
-                               item.element = item._backup;
-                               item._backup = null;
-                       }
-               },this); 
-       },
-
-       _forgetItem: function(item){
-               var element = item.element;
-               var index = this._getItemIndex(this._newItems, element);
-               if(index >= 0){
-                       this._newItems.splice(index, 1);
-               }
-               index = this._getItemIndex(this._deletedItems, element);
-               if(index >= 0){
-                       this._deletedItems.splice(index, 1);
-               }
-               index = this._getItemIndex(this._modifiedItems, element);
-               if(index >= 0){
-                       this._modifiedItems.splice(index, 1);
-               }
-       },
-
-       _getDocument: function(element){
-               if(element){
-                       return element.ownerDocument;  //DOMDocument
-               }else if(!this._document){
-                       return dojox.data.dom.createDocument(); // DOMDocument
-               }
-       },
-
-       _getRootElement: function(element){
-               while(element.parentNode){
-                       element = element.parentNode;
-               }
-               return element; //DOMElement
-       }
-
-});
-
-//FIXME: Is a full class here really needed for containment of the item or would
-//an anon object work fine?
-dojo.declare("dojox.data.XmlItem", null, {
-       constructor: function(element, store) {
-               //      summary:
-               //              Initialize with an XML element
-               //      element:
-               //              An XML element
-               //      store:
-               //              The containing store, if any.
-               this.element = element;
-               this.store = store;
-       }, 
-       //      summary:
-       //              A data item of 'XmlStore'
-       //      description:
-       //              This class represents an item of 'XmlStore' holding an XML element.
-       //              'element'
-       //      element:
-       //              An XML element
-
-       toString: function() {
-               //      summary:
-               //              Return a value of the first text child of the element
-               //      returns:
-               //              a value of the first text child of the element
-               var str = "";
-               if (this.element) {
-                       for (var i = 0; i < this.element.childNodes.length; i++) {
-                               var node = this.element.childNodes[i];
-                               if (node.nodeType === 3) {
-                                       str = node.nodeValue;
-                                       break;
-                               }
-                       }
-               }
-               return str;     //String
-       }
-
-});
-dojo.extend(dojox.data.XmlStore,dojo.data.util.simpleFetch);
-
-}