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