PageSourceSearch

https://eoffice.ad.u-fukui.ac.jp/popeye/common/jkl-parsexml.js

js u-fukui.ac.jp collected 2026-10-01 11:33:37 UTC 28,228 bytes, 706 lines download raw bytes

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.