DataDriver.xml

class webix.DataDriver.xml()

Datadriver.xml mixin

References

helpers
assert_error(), debug_code(), ready().

External references

Official documentation page.

Code

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
webix.DataDriver.xml={
    _isValidXML:function(data){
        if (!data || !data.documentElement)
            return null;
        if (data.getElementsByTagName("parsererror").length)
            return null;
        return data;
    },
    //convert xml string to xml object if necessary
    toObject:function(text, response){
        var data = response ? (response.rawxml ? response.rawxml() : response) :null;
        if (this._isValidXML(data))
            return data;
        if (typeof text == "string")
            data = this.fromString(text.replace(/^[\s]+/,""));
        else
            data = text;

        if (this._isValidXML(data))
            return data;
        return null;
    },
    //get array of records
    getRecords:function(data){
        return this.xpath(data,this.records);
    },
    records:"/*/item",
    child:"item",
    config:"/*/config",
    //get hash of properties for single record
    getDetails:function(data){
        return this.tagToObject(data,{});
    },
    getOptions:function(){
        return false;
    },
    //get count of data and position at which new data_loading need to be inserted
    getInfo:function(data){

        var config = this.xpath(data, this.config);
        if (config.length)
            config = this.assignTypes(this.tagToObject(config[0],{}));
        else
            config = null;

        return {
            size:(data.documentElement.getAttribute("total_count")||0),
            from:(data.documentElement.getAttribute("pos")||0),
            parent:(data.documentElement.getAttribute("parent")||0),
            config:config,
            key:(data.documentElement.getAttribute("webix_security")||null)
        };
    },
    //xpath helper
    xpath:function(xml,path){
        if (window.XPathResult){    //FF, KHTML, Opera
         var node=xml;
         if(xml.nodeName.indexOf("document")==-1)
         xml=xml.ownerDocument;
         var res = [];
         var col = xml.evaluate(path, node, null, XPathResult.ANY_TYPE, null);
         var temp = col.iterateNext();
         while (temp){
            res.push(temp);
            temp = col.iterateNext();
        }
        return res;
        }
        else {
            var test = true;
            try {
                if (typeof(xml.selectNodes)=="undefined")
                    test = false;
            } catch(e){ /*IE7 and below can't operate with xml object*/ }
            //IE
            if (test)
                return xml.selectNodes(path);
            else {
                //there is no interface to do XPath
                //use naive approach
                var name = path.split("/").pop();

                return xml.getElementsByTagName(name);
            }
        }
    },
    assignTypes:function(obj){
        for (var k in obj){
            var test = obj[k];
            if (typeof test == "object")
                this.assignTypes(test);
            else if (typeof test == "string"){
                if (test === "")
                    continue;
                if (test == "true")
                    obj[k] = true;
                else if (test == "false")
                    obj[k] = false;
                else if (test == test*1)
                    obj[k] = obj[k]*1;
            }
        }
        return obj;
    },
    //convert xml tag to js object, all subtags and attributes are mapped to the properties of result object
    tagToObject:function(tag,z){
        var isArray = tag.nodeType == 1 && tag.getAttribute("stack");
        var hasSubTags = 0;

        if (!isArray){
            z=z||{};


            //map attributes
            var a=tag.attributes;
            if(a && a.length)
                for (var i=0; i<a.length; i++){
                    z[a[i].name]=a[i].value;
                    hasSubTags = 1;
                }

            //map subtags
            var b=tag.childNodes;
            for (var i=0; i<b.length; i++)
                if (b[i].nodeType==1){
                    var name = b[i].tagName;
                    if (z[name]){
                        if (typeof z[name].push != "function")
                            z[name] = [z[name]];
                        z[name].push(this.tagToObject(b[i],{}));
                    } else
                        z[name]=this.tagToObject(b[i],{});    //sub-object for complex subtags
                    hasSubTags = 2;
                }

            if (!hasSubTags)
                return this.nodeValue(tag);
            //each object will have its text content as "value" property
            //only if has not sub tags
            if (hasSubTags < 2)
                z.value = z.value||this.nodeValue(tag);

        } else {
            z = [];
            var b=tag.childNodes;
            for (var i=0; i<b.length; i++)
                if (b[i].nodeType==1)
                    z.push(this.tagToObject(b[i],{}));
        }

        return z;
    },
    //get value of xml node
    nodeValue:function(node){
        if (node.firstChild){
            return node.firstChild.wholeText || node.firstChild.data;
        }
        return "";
    },
    //convert XML string to XML object
    fromString:function(xmlString){
        try{
            if (window.DOMParser)        // FF, KHTML, Opera
                return (new DOMParser()).parseFromString(xmlString,"text/xml");
            if (window.ActiveXObject){    // IE, utf-8 only
                var temp=new ActiveXObject("Microsoft.xmlDOM");
                temp.loadXML(xmlString);
                return temp;
            }
        } catch(e){
            webix.assert_error(e);
            return null;
        }
        webix.assert_error("Load from xml string is not supported");
    }
};


webix.debug_code(function(){
    webix.debug_load_event = webix.attachEvent("onLoadError", function(text, xml, xhttp, owner){
        text = text || "[EMPTY DATA]";
        var error_text = "Data loading error, check console for details";
        if (text.indexOf("<?php") === 0)
            error_text = "PHP support missed";
        else if (text.indexOf("WEBIX_ERROR:") === 0)
            error_text = text.replace("WEBIX_ERROR:","");

        if (webix.message)
            webix.message({
                type:"debug",
                text:error_text,
                expire:-1
            });
        if (window.console){
            var logger = window.console;
            logger.log("Data loading error");
            logger.log("Object:", owner);
            logger.log("Response:", text);
            logger.log("XHTTP:", xhttp);
        }
    });

    webix.ready(function(){
        var path = document.location.href;
        if (path.indexOf("file:")===0){
            if (webix.message)
                webix.message({
                    type:"error",
                    text:"Please open sample by http,<br>not as file://",
                    expire:-1
                });
            else
                window.alert("Please open sample by http, not as file://");
        }
    });

});



//UI interface