1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 /** 28 * a SAX Parser 29 * @class 30 * @extends cc.Class 31 */ 32 cc.SAXParser = cc.Class.extend(/** @lends cc.SAXParser# */{ 33 xmlDoc:null, 34 parser:null, 35 xmlList:[], 36 plist:[], 37 38 /** 39 * parse a xml from a string (xmlhttpObj.responseText) 40 * @param {String} textxml plist xml contents 41 * @return {Array} plist object array 42 */ 43 parse:function (textxml) { 44 var textxml = this.getList(textxml); 45 // get a reference to the requested corresponding xml file 46 if (window.DOMParser) { 47 this.parser = new DOMParser(); 48 this.xmlDoc = this.parser.parseFromString(textxml, "text/xml"); 49 } else // Internet Explorer (untested!) 50 { 51 this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 52 this.xmlDoc.async = "false"; 53 this.xmlDoc.loadXML(textxml); 54 } 55 if (this.xmlDoc == null) { 56 cc.log("cocos2d:xml " + this.xmlDoc + " not found!"); 57 } 58 var plist = this.xmlDoc.documentElement; 59 if (plist.tagName != 'plist') { 60 throw "cocos2d:Not a plist file" 61 } 62 // Get first real node 63 var node = null; 64 for (var i = 0, len = plist.childNodes.length; i < len; i++) { 65 node = plist.childNodes[i]; 66 if (node.nodeType == 1) { 67 break 68 } 69 } 70 this.plist = this._parseNode(node); 71 return this.plist; 72 }, 73 74 /** 75 * parse a tilemap xml from a string (xmlhttpObj.responseText) 76 * @param {String} textxml tilemap xml content 77 * @return {Document} xml document 78 */ 79 tmxParse:function (textxml) { 80 var textxml = this.getList(textxml); 81 // get a reference to the requested corresponding xml file 82 if (window.DOMParser) { 83 this.parser = new DOMParser(); 84 this.xmlDoc = this.parser.parseFromString(textxml, "text/xml"); 85 } else // Internet Explorer (untested!) 86 { 87 this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 88 this.xmlDoc.async = "false"; 89 this.xmlDoc.loadXML(textxml); 90 } 91 if (this.xmlDoc == null) { 92 cc.log("cocos2d:xml " + this.xmlDoc + " not found!"); 93 } 94 return this.xmlDoc; 95 }, 96 97 _parseNode:function (node) { 98 var data = null; 99 switch (node.tagName) { 100 case 'dict': 101 data = this._parseDict(node); 102 break; 103 case 'array': 104 data = this._parseArray(node); 105 break; 106 case 'string': 107 if (node.childNodes.length == 1) { 108 data = node.firstChild.nodeValue; 109 } else { 110 //handle Firefox's 4KB nodeValue limit 111 data = ""; 112 for (var i = 0; i < node.childNodes.length; i++) { 113 data += node.childNodes[i].nodeValue; 114 } 115 } 116 break; 117 case 'false': 118 data = false; 119 break; 120 case 'true': 121 data = true; 122 break; 123 case 'real': 124 data = parseFloat(node.firstChild.nodeValue); 125 break; 126 case 'integer': 127 data = parseInt(node.firstChild.nodeValue, 10); 128 break; 129 } 130 131 return data; 132 }, 133 134 _parseArray:function (node) { 135 var data = []; 136 for (var i = 0, len = node.childNodes.length; i < len; i++) { 137 var child = node.childNodes[i]; 138 if (child.nodeType != 1) { 139 continue; 140 } 141 data.push(this._parseNode(child)); 142 } 143 return data; 144 }, 145 146 _parseDict:function (node) { 147 var data = {}; 148 149 var key = null; 150 for (var i = 0, len = node.childNodes.length; i < len; i++) { 151 var child = node.childNodes[i]; 152 if (child.nodeType != 1) { 153 continue; 154 } 155 156 // Grab the key, next noe should be the value 157 if (child.tagName == 'key') { 158 key = child.firstChild.nodeValue; 159 } else { 160 // Parse the value node 161 data[key] = this._parseNode(child); 162 } 163 } 164 return data; 165 }, 166 167 /** 168 * Preload plist file 169 * @param {String} filePath 170 */ 171 preloadPlist:function (filePath) { 172 filePath = cc.FileUtils.getInstance().fullPathFromRelativePath(filePath); 173 174 if (window.XMLHttpRequest) { 175 // for IE7+, Firefox, Chrome, Opera, Safari brower 176 var xmlhttp = new XMLHttpRequest(); 177 // is xml file? 178 if (xmlhttp.overrideMimeType) 179 xmlhttp.overrideMimeType('text/xml'); 180 } else { 181 // for IE6, IE5 brower 182 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 183 } 184 if (xmlhttp != null) { 185 var that = this; 186 xmlhttp.onreadystatechange = function () { 187 if (xmlhttp.readyState == 4) { 188 if (xmlhttp.responseText) { 189 cc.Loader.getInstance().onResLoaded(); 190 that.xmlList[filePath] = xmlhttp.responseText; 191 xmlhttp = null; 192 } else { 193 cc.Assert("cocos2d:There was a problem retrieving the xml data:" + xmlhttp.statusText); 194 } 195 } 196 }; 197 // load xml 198 xmlhttp.open("GET", filePath, true); 199 xmlhttp.send(null); 200 } else { 201 cc.Assert("cocos2d:Your browser does not support XMLHTTP."); 202 } 203 }, 204 205 /** 206 * get filename from filepath 207 * @param {String} filePath 208 * @return {String} 209 */ 210 getName:function (filePath) { 211 var startPos = filePath.lastIndexOf("/", filePath.length) + 1; 212 var endPos = filePath.lastIndexOf(".", filePath.length); 213 return filePath.substring(startPos, endPos); 214 }, 215 216 /** 217 * get file extension name from filepath 218 * @param {String} filePath 219 * @return {String} 220 */ 221 getExt:function (filePath) { 222 var startPos = filePath.lastIndexOf(".", filePath.length) + 1; 223 return filePath.substring(startPos, filePath.length); 224 }, 225 226 /** 227 * get value by key from xmlList 228 * @param {String} key 229 * @return {String} xml content 230 */ 231 getList:function (key) { 232 if (this.xmlList != null) { 233 return this.xmlList[key]; 234 } else { 235 return null; 236 } 237 } 238 }); 239 240 /** 241 * get a singleton SAX parser 242 * @function 243 * @return {cc.SAXParser} 244 */ 245 cc.SAXParser.getInstance = function () { 246 if (!this._instance) { 247 this._instance = new cc.SAXParser(); 248 } 249 return this._instance; 250 }; 251 252 cc.SAXParser._instance = null;