1/* 2Copyright (c) 2005-2010 Yusuke Kawasaki. All rights reserved. 3 4Redistribution and use in source and binary forms, with or without 5modification, are permitted provided that the following conditions 6are met: 7 81. Redistributions of source code must retain the above copyright 9 notice, this list of conditions and the following disclaimer. 102. Redistributions in binary form must reproduce the above copyright 11 notice, this list of conditions and the following disclaimer in 12 the documentation and/or other materials provided with the 13 distribution. 143. Neither the name of the author nor the names of its contributors 15 may be used to endorse or promote products derived from this 16 software without specific, prior written permission. 17 18THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 24BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 28OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29SUCH DAMAGE. 30*/ 31// ================================================================ 32// jkl-parsexml.js ---- JavaScript Kantan Library for Parsing XML 33// http://www.kawa.net/works/js/jkl/parsexml.html 34// ================================================================ 35// v0.01 2005/05/18 first release 36// v0.02 2005/05/20 Opera 8.0beta may be abailable but somtimes crashed 37// v0.03 2005/05/20 overrideMimeType( "text/xml" ); 38// v0.04 2005/05/21 class variables: REQUEST_TYPE, RESPONSE_TYPE 39// v0.05 2005/05/22 use Msxml2.DOMDocument.5.0 for GET method on IE6 40// v0.06 2005/05/22 CDATA_SECTION_NODE 41// v0.07 2005/05/23 use Microsoft.XMLDOM for GET method on IE6 42// v0.10 2005/10/11 new function: JKL.ParseXML.HTTP.responseText() 43// v0.11 2005/10/13 new sub class: JKL.ParseXML.Text, JSON and DOM. 44// v0.12 2005/10/14 new sub class: JKL.ParseXML.CSV and CSVmap. 45// v0.13 2005/10/28 bug fixed: TEXT_NODE regexp for white spaces 46// v0.14 2005/11/06 bug fixed: TEXT_NODE regexp at Safari 47// v0.15 2005/11/08 bug fixed: JKL.ParseXML.CSV.async() method 48// v0.16 2005/11/15 new sub class: LoadVars, and UTF-8 text on Safari 49// v0.18 2005/11/16 improve: UTF-8 text file on Safari 50// v0.19 2006/02/03 use XMLHTTPRequest instead of ActiveX on IE7,iCab 51// v0.20 2006/03/22 (skipped) 52// v0.21 2006/11/30 use ActiveX again on IE7 53// v0.22 2007/01/04 JKL.ParseXML.JSON.parseResponse() updated 54// v0.22c 2010/01/07 New BSD License declaration added. no code changed 55// ================================================================ 56 57if ( typeof(JKL) == 'undefined' ) JKL = function() {}; 58 59// ================================================================ 60// class: JKL.ParseXML 61 62JKL.ParseXML = function ( url, query, method ) { 63 // debug.print( "new JKL.ParseXML( '"+url+"', '"+query+"', '"+method+"' );" ); 64 this.http = new JKL.ParseXML.HTTP( url, query, method, false ); 65 return this; 66}; 67 68// ================================================================ 69// class variables 70 71JKL.ParseXML.VERSION = "0.22"; 72JKL.ParseXML.MIME_TYPE_XML = "text/xml"; 73JKL.ParseXML.MAP_NODETYPE = [ 74 "", 75 "ELEMENT_NODE", // 1 76 "ATTRIBUTE_NODE", // 2 77 "TEXT_NODE", // 3 78 "CDATA_SECTION_NODE", // 4 79 "ENTITY_REFERENCE_NODE", // 5 80 "ENTITY_NODE", // 6 81 "PROCESSING_INSTRUCTION_NODE", // 7 82 "COMMENT_NODE", // 8 83 "DOCUMENT_NODE", // 9 84 "DOCUMENT_TYPE_NODE", // 10 85 "DOCUMENT_FRAGMENT_NODE", // 11 86 "NOTATION_NODE" // 12 87]; 88 89// ================================================================ 90// define callback function (ajax) 91 92JKL.ParseXML.prototype.async = function ( func, args ) { 93 this.callback_func = func; // callback function 94 this.callback_arg = args; // first argument 95}; 96 97JKL.ParseXML.prototype.onerror = function ( func, args ) { 98 this.onerror_func = func; // callback function 99}; 100 101// ================================================================ 102// method: parse() 103// return: parsed object 104// Download a file from remote server and parse it. 105 106JKL.ParseXML.prototype.parse = function () { 107 if ( ! this.http ) return; 108 109 // set onerror call back 110 if ( this.onerror_func ) {
111 this.http.onerror( this.onerror_func ); 112 } 113 114 if ( this.callback_func ) { // async mode 115 var copy = this; 116 var proc = function() { 117 if ( ! copy.http ) return; 118 var data = copy.parseResponse(); 119 copy.callback_func( data, copy.callback_arg ); // call back 120 }; 121 this.http.async( proc ); 122 } 123 124 this.http.load(); 125 126 if ( ! this.callback_func ) { // sync mode 127 var data = this.parseResponse(); 128 return data; 129 } 130}; 131 132// ================================================================ 133// every child/children into array 134JKL.ParseXML.prototype.setOutputArrayAll = function () { 135 this.setOutputArray( true ); 136} 137// a child into scalar, children into array 138JKL.ParseXML.prototype.setOutputArrayAuto = function () { 139 this.setOutputArray( null ); 140} 141// every child/children into scalar (first sibiling only) 142JKL.ParseXML.prototype.setOutputArrayNever = function () { 143 this.setOutputArray( false ); 144} 145// specified child/children into array, other child/children into scalar 146JKL.ParseXML.prototype.setOutputArrayElements = function ( list ) { 147 this.setOutputArray( list ); 148} 149// specify how to treate child/children into scalar/array 150JKL.ParseXML.prototype.setOutputArray = function ( mode ) { 151 if ( typeof(mode) == "string" ) { 152 mode = [ mode ]; // string into array 153 } 154 if ( mode && typeof(mode) == "object" ) { 155 if ( mode.length < 0 ) { 156 mode = false; // false when array == [] 157 } else { 158 var hash = {}; 159 for( var i=0; i<mode.length; i++ ) { 160 hash[mode[i]] = true; 161 } 162 mode = hash; // array into hashed array 163 if ( mode["*"] ) { 164 mode = true; // true when includes "*" 165 } 166 } 167 } 168 this.usearray = mode; 169} 170 171// ================================================================ 172// method: parseResponse() 173 174JKL.ParseXML.prototype.parseResponse = function () { 175 var root = this.http.documentElement(); 176 var data = this.parseDocument( root ); 177 return data; 178} 179 180// ================================================================ 181// convert from DOM root node to JavaScript Object 182// method: parseElement( rootElement ) 183 184JKL.ParseXML.prototype.parseDocument = function ( root ) { 185 // debug.print( "parseDocument: "+root ); 186 if ( ! root ) return; 187 188 var ret = this.parseElement( root ); // parse root node 189 // debug.print( "parsed: "+ret ); 190 191 if ( this.usearray == true ) { // always into array 192 ret = [ ret ]; 193 } else if ( this.usearray == false ) { // always into scalar 194 // 195 } else if ( this.usearray == null ) { // automatic 196 // 197 } else if ( this.usearray[root.nodeName] ) { // specified tag 198 ret = [ ret ]; 199 } 200 201 var json = {}; 202 json[root.nodeName] = ret; // root nodeName 203 return json; 204}; 205 206// ================================================================ 207// convert from DOM Element to JavaScript Object 208// method: parseElement( element ) 209 210JKL.ParseXML.prototype.parseElement = function ( elem ) { 211 // debug.print( "nodeType: "+JKL.ParseXML.MAP_NODETYPE[elem.nodeType]+" <"+elem.nodeName+">" ); 212 213 // COMMENT_NODE 214 215 if ( elem.nodeType == 7 ) { 216 return; 217 } 218 219 // TEXT_NODE CDATA_SECTION_NODE 220 221 if ( elem.nodeType == 3 || elem.nodeType == 4 ) { 222 // var bool = elem.nodeValue.match( /[^\u0000-\u0020]/ ); 223 var bool = elem.nodeValue.match( /[^\x00-\x20]/ ); // for Safari 224 if ( bool == null ) return; // ignore white spaces 225 // debug.print( "TEXT_NODE: "+elem.nodeValue.length+ " "+bool ); 226 return elem.nodeValue; 227 } 228 229 var retval; 230 var cnt = {}; 231 232 // parse attributes 233 234 if ( elem.attributes && elem.attributes.length ) { 235 retval = {}; 236 for ( var i=0; i<elem.attributes.length; i++ ) { 237 var key = elem.attributes[i].nodeName;
238 if ( typeof(key) != "string" ) continue; 239 var val = elem.attributes[i].nodeValue; 240 if ( ! val ) continue; 241 if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0; 242 cnt[key] ++; 243 this.addNode( retval, key, cnt[key], val ); 244 } 245 } 246 247 // parse child nodes (recursive) 248 249 if ( elem.childNodes && elem.childNodes.length ) { 250 var textonly = true; 251 if ( retval ) textonly = false; // some attributes exists 252 for ( var i=0; i<elem.childNodes.length && textonly; i++ ) { 253 var ntype = elem.childNodes[i].nodeType; 254 if ( ntype == 3 || ntype == 4 ) continue; 255 textonly = false; 256 } 257 if ( textonly ) { 258 if ( ! retval ) retval = ""; 259 for ( var i=0; i<elem.childNodes.length; i++ ) { 260 retval += elem.childNodes[i].nodeValue; 261 } 262 } else { 263 if ( ! retval ) retval = {}; 264 for ( var i=0; i<elem.childNodes.length; i++ ) { 265 var key = elem.childNodes[i].nodeName; 266 if ( typeof(key) != "string" ) continue; 267 var val = this.parseElement( elem.childNodes[i] ); 268 if ( ! val ) continue; 269 if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0; 270 cnt[key] ++; 271 this.addNode( retval, key, cnt[key], val ); 272 } 273 } 274 } 275 return retval; 276}; 277 278// ================================================================ 279// method: addNode( hash, key, count, value ) 280 281JKL.ParseXML.prototype.addNode = function ( hash, key, cnts, val ) { 282 if ( this.usearray == true ) { // into array 283 if ( cnts == 1 ) hash[key] = []; 284 hash[key][hash[key].length] = val; // push 285 } else if ( this.usearray == false ) { // into scalar 286 if ( cnts == 1 ) hash[key] = val; // only 1st sibling 287 } else if ( this.usearray == null ) { 288 if ( cnts == 1 ) { // 1st sibling 289 hash[key] = val; 290 } else if ( cnts == 2 ) { // 2nd sibling 291 hash[key] = [ hash[key], val ]; 292 } else { // 3rd sibling and more 293 hash[key][hash[key].length] = val; 294 } 295 } else if ( this.usearray[key] ) { 296 if ( cnts == 1 ) hash[key] = []; 297 hash[key][hash[key].length] = val; // push 298 } else { 299 if ( cnts == 1 ) hash[key] = val; // only 1st sibling 300 } 301}; 302 303// ================================================================ 304// class: JKL.ParseXML.Text 305 306JKL.ParseXML.Text = function ( url, query, method ) { 307 // debug.print( "new JKL.ParseXML.Text( '"+url+"', '"+query+"', '"+method+"' );" ); 308 this.http = new JKL.ParseXML.HTTP( url, query, method, true ); 309 return this; 310}; 311 312JKL.ParseXML.Text.prototype.parse = JKL.ParseXML.prototype.parse; 313JKL.ParseXML.Text.prototype.async = JKL.ParseXML.prototype.async; 314JKL.ParseXML.Text.prototype.onerror = JKL.ParseXML.prototype.onerror; 315 316JKL.ParseXML.Text.prototype.parseResponse = function () { 317 var data = this.http.responseText(); 318 return data; 319} 320 321// ================================================================ 322// class: JKL.ParseXML.JSON 323 324JKL.ParseXML.JSON = function ( url, query, method ) { 325 // debug.print( "new JKL.ParseXML.JSON( '"+url+"', '"+query+"', '"+method+"' );" ); 326 this.http = new JKL.ParseXML.HTTP( url, query, method, true ); 327 return this; 328}; 329 330JKL.ParseXML.JSON.prototype.parse = JKL.ParseXML.prototype.parse; 331JKL.ParseXML.JSON.prototype.async = JKL.ParseXML.prototype.async; 332JKL.ParseXML.JSON.prototype.onerror = JKL.ParseXML.prototype.onerror; 333 334JKL.ParseXML.JSON.prototype.parseResponse = function () { 335 var text = this.http.responseText(); 336 // http://www.antimon2.atnifty.com/2007/01/jklparsexmljson.html 337 if ( typeof(text) == 'undefined' ) return; 338 if ( ! text.length ) return; 339 var data = eval( "("+text+")" ); 340 return data; 341} 342 343// ================================================================
344// class: JKL.ParseXML.DOM 345 346JKL.ParseXML.DOM = function ( url, query, method ) { 347 // debug.print( "new JKL.ParseXML.DOM( '"+url+"', '"+query+"', '"+method+"' );" ); 348 this.http = new JKL.ParseXML.HTTP( url, query, method, false ); 349 return this; 350}; 351 352JKL.ParseXML.DOM.prototype.parse = JKL.ParseXML.prototype.parse; 353JKL.ParseXML.DOM.prototype.async = JKL.ParseXML.prototype.async; 354JKL.ParseXML.DOM.prototype.onerror = JKL.ParseXML.prototype.onerror; 355 356JKL.ParseXML.DOM.prototype.parseResponse = function () { 357 var data = this.http.documentElement(); 358 return data; 359} 360 361// ================================================================ 362// class: JKL.ParseXML.CSV 363 364JKL.ParseXML.CSV = function ( url, query, method ) { 365 // debug.print( "new JKL.ParseXML.CSV( '"+url+"', '"+query+"', '"+method+"' );" ); 366 this.http = new JKL.ParseXML.HTTP( url, query, method, true ); 367 return this; 368}; 369 370JKL.ParseXML.CSV.prototype.parse = JKL.ParseXML.prototype.parse; 371JKL.ParseXML.CSV.prototype.async = JKL.ParseXML.prototype.async; 372JKL.ParseXML.CSV.prototype.onerror = JKL.ParseXML.prototype.onerror; 373 374JKL.ParseXML.CSV.prototype.parseResponse = function () { 375 var text = this.http.responseText(); 376 var data = this.parseCSV( text ); 377 return data; 378} 379 380JKL.ParseXML.CSV.prototype.parseCSV = function ( text ) { 381 text = text.replace( /\r\n?/g, "\n" ); // new line character 382 var pos = 0; 383 var len = text.length; 384 var table = []; 385 while( pos<len ) { 386 var line = []; 387 while( pos<len ) { 388 if ( text.charAt(pos) == '"' ) { // "..." quoted column 389 var nextquote = text.indexOf( '"', pos+1 ); 390 while ( nextquote<len && nextquote > -1 ) { 391 if ( text.charAt(nextquote+1) != '"' ) { 392 break; // end of column 393 } 394 nextquote = text.indexOf( '"', nextquote+2 ); 395 } 396 if ( nextquote < 0 ) { 397 // unclosed quote 398 } else if ( text.charAt(nextquote+1) == "," ) { // end of column 399 var quoted = text.substr( pos+1, nextquote-pos-1 ); 400 quoted = quoted.replace(/""/g,'"'); 401 line[line.length] = quoted; 402 pos = nextquote+2; 403 continue; 404 } else if ( text.charAt(nextquote+1) == "\n" || // end of line 405 len==nextquote+1 ) { // end of file 406 var quoted = text.substr( pos+1, nextquote-pos-1 ); 407 quoted = quoted.replace(/""/g,'"'); 408 line[line.length] = quoted; 409 pos = nextquote+2; 410 break; 411 } else { 412 // invalid column 413 } 414 } 415 var nextcomma = text.indexOf( ",", pos ); 416 var nextnline = text.indexOf( "\n", pos ); 417 if ( nextnline < 0 ) nextnline = len; 418 if ( nextcomma > -1 && nextcomma < nextnline ) { 419 line[line.length] = text.substr( pos, nextcomma-pos ); 420 pos = nextcomma+1; 421 } else { // end of line 422 line[line.length] = text.substr( pos, nextnline-pos ); 423 pos = nextnline+1; 424 break; 425 } 426 } 427 if ( line.length >= 0 ) { 428 table[table.length] = line; // push line 429 } 430 } 431 if ( table.length < 0 ) return; // null data 432 return table; 433}; 434 435// ================================================================ 436// class: JKL.ParseXML.CSVmap 437 438JKL.ParseXML.CSVmap = function ( url, query, method ) { 439 // debug.print( "new JKL.ParseXML.CSVmap( '"+url+"', '"+query+"', '"+method+"' );" ); 440 this.http = new JKL.ParseXML.HTTP( url, query, method, true ); 441 return this; 442}; 443 444JKL.ParseXML.CSVmap.prototype.parse = JKL.ParseXML.prototype.parse; 445JKL.ParseXML.CSVmap.prototype.async = JKL.ParseXML.prototype.async; 446JKL.ParseXML.CSVmap.prototype.onerror = JKL.ParseXML.prototype.onerror; 447JKL.ParseXML.CSVmap.prototype.parseCSV = JKL.ParseXML.CSV.prototype.parseCSV; 448 449JKL.ParseXML.CSVmap.prototype.parseResponse = function () { 450 var text = this.http.responseText(); 451 var source = this.parseCSV( text ); 452 if ( ! source ) return; 453 if ( source.length < 0 ) return; 454
455 var title = source.shift(); // first line as title 456 var data = []; 457 for( var i=0; i<source.length; i++ ) { 458 var hash = {}; 459 for( var j=0; j<title.length && j<source[i].length; j++ ) { 460 hash[title[j]] = source[i][j]; // array to map 461 } 462 data[data.length] = hash; // push line 463 } 464 return data; 465} 466 467// ================================================================ 468// class: JKL.ParseXML.LoadVars 469 470JKL.ParseXML.LoadVars = function ( url, query, method ) { 471 // debug.print( "new JKL.ParseXML.LoadVars( '"+url+"', '"+query+"', '"+method+"' );" ); 472 this.http = new JKL.ParseXML.HTTP( url, query, method, true ); 473 return this; 474}; 475 476JKL.ParseXML.LoadVars.prototype.parse = JKL.ParseXML.prototype.parse; 477JKL.ParseXML.LoadVars.prototype.async = JKL.ParseXML.prototype.async; 478JKL.ParseXML.LoadVars.prototype.onerror = JKL.ParseXML.prototype.onerror; 479 480JKL.ParseXML.LoadVars.prototype.parseResponse = function () { 481 var text = this.http.responseText(); 482 text = text.replace( /\r\n?/g, "\n" ); // new line character 483 var hash = {}; 484 var list = text.split( "&" ); 485 for( var i=0; i<list.length; i++ ) { 486 var eq = list[i].indexOf( "=" ); 487 if ( eq > -1 ) { 488 var key = decodeURIComponent(list[i].substr(0,eq).replace("+","%20")); 489 var val = decodeURIComponent(list[i].substr(eq+1).replace("+","%20")); 490 hash[key] = val; 491 } else { 492 hash[list[i]] = ""; 493 } 494 } 495 return hash; 496}; 497 498// ================================================================ 499// class: JKL.ParseXML.HTTP 500// constructer: new JKL.ParseXML.HTTP() 501 502JKL.ParseXML.HTTP = function( url, query, method, textmode ) { 503 // debug.print( "new JKL.ParseXML.HTTP( '"+url+"', '"+query+"', '"+method+"', '"+textmode+"' );" ); 504 this.url = url; 505 if ( typeof(query) == "string" ) { 506 this.query = query; 507 } else { 508 this.query = ""; 509 } 510 if ( method ) { 511 this.method = method; 512 } else if ( typeof(query) == "string" ) { 513 this.method = "POST"; 514 } else { 515 this.method = "GET"; 516 } 517 this.textmode = textmode ? true : false; 518 this.req = null; 519 this.xmldom_flag = false; 520 this.onerror_func = null; 521 this.callback_func = null; 522 this.already_done = null; 523 return this; 524}; 525 526// ================================================================ 527// class variables 528 529JKL.ParseXML.HTTP.REQUEST_TYPE = "application/x-www-form-urlencoded"; 530JKL.ParseXML.HTTP.ACTIVEX_XMLDOM = "Microsoft.XMLDOM"; // Msxml2.DOMDocument.5.0 531JKL.ParseXML.HTTP.ACTIVEX_XMLHTTP = "Microsoft.XMLHTTP"; // Msxml2.XMLHTTP.3.0 532JKL.ParseXML.HTTP.EPOCH_TIMESTAMP = "Thu, 01 Jun 1970 00:00:00 GMT" 533 534// ================================================================ 535 536JKL.ParseXML.HTTP.prototype.onerror = JKL.ParseXML.prototype.onerror; 537JKL.ParseXML.HTTP.prototype.async = function( func ) { 538 this.async_func = func; 539} 540 541// ================================================================ 542// [IE+IXMLDOMElement] 543// XML text/xml OK 544// XML application/rdf+xml OK 545// TEXT text/plain NG 546// TEXT others NG 547// [IE+IXMLHttpRequest] 548// XML text/xml OK 549// XML application/rdf+xml NG 550// TEXT text/plain OK 551// TEXT others OK 552// [Firefox+XMLHttpRequest] 553// XML text/xml OK 554// XML application/rdf+xml OK (overrideMimeType) 555// TEXT text/plain OK 556// TEXT others OK (overrideMimeType) 557// [Opera+XMLHttpRequest] 558// XML text/xml OK 559// XML application/rdf+xml OK 560// TEXT text/plain OK 561// TEXT others OK 562// ================================================================ 563 564JKL.ParseXML.HTTP.prototype.load = function() { 565 // create XMLHttpRequest object 566 if ( window.XMLHttpRequest ) { // Firefox, Opera, iCab 567 // debug.print( "new XMLHttpRequest()" ); 568 this.req = new XMLHttpRequest(); 569 } else if ( window.ActiveXObject ) { // IE5.5,6,7 570 var activex = JKL.ParseXML.HTTP.ACTIVEX_XMLHTTP; // IXMLHttpRequest 571 if ( this.method == "GET" && ! this.textmode ) { 572 // use IXMLDOMElement to accept any mime types 573 // because overrideMimeType() is not available on IE6 574 activex = JKL.ParseXML.HTTP.ACTIVEX_XMLDOM; // IXMLDOMElement 575 } 576 // debug.print( "new ActiveXObject( '"+activex+"' )" ); 577 this.req = new ActiveXObject( activex ); 578 } 579 580 // async mode when call back function is specified 581 var async_flag = this.async_func ? true : false; 582 // debug.print( "async: "+ async_flag ); 583 584 // open for XMLHTTPRequest (not for IXMLDOMElement) 585 if ( typeof(this.req.send) != "undefined" ) { 586 // debug.print( "open( '"+this.method+"', '"+this.url+"', "+async_flag+" );" ); 587 this.req.open( this.method, this.url, async_flag ); 588 } 589 590// // If-Modified-Since: Thu, 01 Jun 1970 00:00:00 GMT 591// if ( typeof(this.req.setRequestHeader) != "undefined" ) { 592// // debug.print( "If-Modified-Since"+JKL.ParseXML.HTTP.EPOCH_TIMESTAMP ); 593// this.req.setRequestHeader( "If-Modified-Since", JKL.ParseXML.HTTP.EPOCH_TIMESTAMP ); 594// } 595 596 // Content-Type: application/x-www-form-urlencoded (request header) 597 // Some server does not accept without request content-type. 598 if ( typeof(this.req.setRequestHeader) != "undefined" ) { 599 // debug.print( "Content-Type: "+JKL.ParseXML.HTTP.REQUEST_TYPE+" (request)" ); 600 this.req.setRequestHeader( "Content-Type", JKL.ParseXML.HTTP.REQUEST_TYPE ); 601 } 602 603 // Content-Type: text/xml (response header) 604 // FireFox does not accept other mime types like application/rdf+xml etc. 605 if ( typeof(this.req.overrideMimeType) != "undefined" && ! this.textmode ) { 606 // debug.print( "Content-Type: "+JKL.ParseXML.MIME_TYPE_XML+" (response)" ); 607 this.req.overrideMimeType( JKL.ParseXML.MIME_TYPE_XML ); 608 } 609 610 // set call back handler when async mode 611 if ( async_flag ) { 612 var copy = this; 613 copy.already_done = false; // not parsed yet 614 var check_func = function () { 615 if ( copy.req.readyState != 4 ) return; 616 // debug.print( "readyState(async): "+copy.req.readyState ); 617 var succeed = copy.checkResponse(); 618 // debug.print( "checkResponse(async): "+succeed ); 619 if ( ! succeed ) return; // failed 620 if ( copy.already_done ) return; // parse only once 621 copy.already_done = true; // already parsed 622 copy.async_func(); // call back async 623 }; 624 this.req.onreadystatechange = check_func; 625 // for document.implementation.createDocument 626 // this.req.onload = check_func; 627 } 628 629 // send the request and query string 630 if ( typeof(this.req.send) != "undefined" ) { 631 // debug.print( "XMLHTTPRequest: send( '"+this.query+"' );" ); 632 this.req.send( this.query ); // XMLHTTPRequest 633 } else if ( typeof(this.req.load) != "undefined" ) { 634 // debug.print( "IXMLDOMElement: load( '"+this.url+"' );" ); 635 this.req.async = async_flag; 636 this.req.load( this.url ); // IXMLDOMElement 637 } 638 639 // just return when async mode 640 if ( async_flag ) return; 641 642 var succeed = this.checkResponse(); 643 // debug.print( "checkResponse(sync): "+succeed ); 644} 645 646// ================================================================ 647// method: checkResponse() 648 649JKL.ParseXML.HTTP.prototype.checkResponse = function() { 650 // parseError on IXMLDOMElement 651 if ( this.req.parseError && this.req.parseError.errorCode != 0 ) { 652 // debug.print( "parseError: "+this.req.parseError.reason ); 653 if ( this.onerror_func ) this.onerror_func( this.req.parseError.reason ); 654 return false; // failed 655 } 656 657 // HTTP response code 658 if ( this.req.status-0 > 0 && 659 this.req.status != 200 && // OK 660 this.req.status != 206 && // Partial Content 661 this.req.status != 304 ) { // Not Modified 662 // debug.print( "status: "+this.req.status ); 663 if ( this.onerror_func ) this.onerror_func( this.req.status ); 664 return false; // failed 665 } 666 667 return true; // succeed 668} 669 670// ================================================================ 671// method: documentElement()
672// return: XML DOM in response body 673 674JKL.ParseXML.HTTP.prototype.documentElement = function() { 675 // debug.print( "documentElement: "+this.req ); 676 if ( ! this.req ) return; 677 if ( this.req.responseXML ) { 678 return this.req.responseXML.documentElement; // XMLHTTPRequest 679 } else { 680 return this.req.documentElement; // IXMLDOMDocument 681 } 682} 683 684// ================================================================ 685// method: responseText() 686// return: text string in response body 687 688JKL.ParseXML.HTTP.prototype.responseText = function() { 689 // debug.print( "responseText: "+this.req ); 690 if ( ! this.req ) return; 691 692 // Safari and Konqueror cannot understand the encoding of text files. 693 if ( navigator.appVersion.match( "KHTML" ) ) { 694 var esc = escape( this.req.responseText ); 695// debug.print( "escape: "+esc ); 696 if ( ! esc.match("%u") && esc.match("%") ) { 697 return decodeURIComponent(esc); 698 } 699 } 700 701 return this.req.responseText; 702} 703 704// ================================================================ 705// http://msdn.microsoft.com/library/en-us/xmlsdk/html/d051f7c5-e882-42e8-a5b6-d1ce67af275c.asp 706// ================================================================
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.