mirror of
				https://github.com/NativeScript/NativeScript.git
				synced 2025-11-04 21:06:45 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			709 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			709 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
	/*
 | 
						|
	new function() {
 | 
						|
		var parser = new EasySAXParser();
 | 
						|
 | 
						|
		parser.ns('rss', { // or false
 | 
						|
			rss: 'http://purl.org/rss/1.0/',
 | 
						|
			atom: 'http://www.w3.org/2005/Atom',
 | 
						|
			xhtml: 'http://www.w3.org/1999/xhtml',
 | 
						|
			media: 'http://search.yahoo.com/mrss/'
 | 
						|
		});
 | 
						|
 | 
						|
 | 
						|
		parser.on('error', function(msg) {
 | 
						|
			//console.log(msg)
 | 
						|
		});
 | 
						|
 | 
						|
		parser.on('startNode', function(elem, attr, uq, tagend, getStrNode) {
 | 
						|
			attr();
 | 
						|
			return;
 | 
						|
			if (tagend) {
 | 
						|
				console.log('   '+str)
 | 
						|
			} else {
 | 
						|
				console.log('+  '+str)
 | 
						|
			};
 | 
						|
		});
 | 
						|
 | 
						|
		parser.on('endNode', function(elem, uq, tagstart, str) {
 | 
						|
			return;
 | 
						|
			if (!tagstart) console.log('-  ' + str)
 | 
						|
		});
 | 
						|
 | 
						|
		parser.on('textNode', function(s, uq) {
 | 
						|
			uq(s);
 | 
						|
			return
 | 
						|
			console.log('   '+s)
 | 
						|
		});
 | 
						|
 | 
						|
		parser.on('cdata', function(data) {
 | 
						|
		});
 | 
						|
 | 
						|
 | 
						|
		parser.on('comment', function(text) {
 | 
						|
			//console.log('--'+text+'--')
 | 
						|
		});
 | 
						|
 | 
						|
		//parser.on('question', function() {}); // <? ... ?>
 | 
						|
		//parser.on('attention', function() {}); // <!XXXXX zzzz="eeee">
 | 
						|
 | 
						|
		console.time('easysax');
 | 
						|
		for(var z=1000;z--;) {
 | 
						|
			parser.parse(xml)
 | 
						|
		};
 | 
						|
		console.timeEnd('easysax');
 | 
						|
	};
 | 
						|
 | 
						|
 | 
						|
	
 | 
						|
	
 | 
						|
	*/
 | 
						|
 | 
						|
// << ------------------------------------------------------------------------ >> //
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
if (typeof exports === 'object' /*&& this == exports*/) {
 | 
						|
	module.exports.EasySAXParser = EasySAXParser;
 | 
						|
};
 | 
						|
 | 
						|
function EasySAXParser() {
 | 
						|
	'use strict';
 | 
						|
 | 
						|
	if (!this) return null;
 | 
						|
 | 
						|
	function nullFunc() {};
 | 
						|
 | 
						|
	var onTextNode = nullFunc, onStartNode = nullFunc, onEndNode = nullFunc, onCDATA = nullFunc, onError = nullFunc, onComment, onQuestion, onAttention;
 | 
						|
	var is_onComment, is_onQuestion, is_onAttention;
 | 
						|
 | 
						|
	var isNamespace = false, useNS , default_xmlns, xmlns
 | 
						|
	, nsmatrix = {xmlns: xmlns}
 | 
						|
	, hasSurmiseNS = false
 | 
						|
	;
 | 
						|
 | 
						|
 | 
						|
	this.on = function(name, cb) {
 | 
						|
		if (typeof cb !== 'function') {
 | 
						|
			if (cb !== null) return;
 | 
						|
		};
 | 
						|
 | 
						|
		switch(name) {
 | 
						|
			case 'error': onError = cb || nullFunc; break;
 | 
						|
			case 'startNode': onStartNode = cb || nullFunc; break;
 | 
						|
			case 'endNode': onEndNode = cb || nullFunc; break;
 | 
						|
			case 'textNode': onTextNode = cb || nullFunc; break;
 | 
						|
			case 'cdata': onCDATA = cb || nullFunc; break;
 | 
						|
 | 
						|
			case 'comment': onComment = cb; is_onComment = !!cb; break;
 | 
						|
			case 'question': onQuestion = cb; is_onQuestion = !!cb; break; // <? ....  ?>
 | 
						|
			case 'attention': onAttention = cb; is_onAttention = !!cb; break; // <!XXXXX zzzz="eeee">
 | 
						|
			
 | 
						|
		}; 
 | 
						|
	};
 | 
						|
 | 
						|
	this.ns = function(root, ns) {
 | 
						|
		if (!root || typeof root !== 'string' || !ns) {
 | 
						|
			return;
 | 
						|
		};
 | 
						|
 | 
						|
		var u, x = {}, ok, v, i;
 | 
						|
 | 
						|
		for(i in ns) {
 | 
						|
			v = ns[i];
 | 
						|
			if (typeof v === 'string') {
 | 
						|
				if (root === v) ok = true;
 | 
						|
				x[i] = v;
 | 
						|
			};
 | 
						|
		};
 | 
						|
		
 | 
						|
		if (ok) {
 | 
						|
			isNamespace = true;
 | 
						|
			default_xmlns = root;
 | 
						|
			useNS = x;
 | 
						|
		};
 | 
						|
	};
 | 
						|
 | 
						|
	this.parse = function(xml) {
 | 
						|
		if (typeof xml !== 'string') {
 | 
						|
			return;
 | 
						|
		};
 | 
						|
 | 
						|
		if (isNamespace) {
 | 
						|
			nsmatrix = {xmlns: default_xmlns};
 | 
						|
 | 
						|
			parse(xml);
 | 
						|
			
 | 
						|
			nsmatrix = false;
 | 
						|
 | 
						|
		} else {
 | 
						|
			parse(xml);
 | 
						|
		};
 | 
						|
 | 
						|
		attr_res = true;
 | 
						|
	};
 | 
						|
 | 
						|
	// -----------------------------------------------------
 | 
						|
 | 
						|
	var xharsQuot={constructor: false, hasOwnProperty: false, isPrototypeOf: false, propertyIsEnumerable: false, toLocaleString: false, toString: false, valueOf: false
 | 
						|
		, quot: '"'
 | 
						|
		, QUOT: '"'
 | 
						|
		, amp: '&'
 | 
						|
		, AMP: '&'
 | 
						|
		, nbsp: '\u00A0'
 | 
						|
		, apos: '\''
 | 
						|
		, lt: '<'
 | 
						|
		, LT: '<'
 | 
						|
		, gt: '>'
 | 
						|
		, GT: '>'
 | 
						|
		, copy: '\u00A9'
 | 
						|
		, laquo: '\u00AB'
 | 
						|
		, raquo: '\u00BB'
 | 
						|
		, reg: '\u00AE'
 | 
						|
		, deg: '\u00B0'
 | 
						|
		, plusmn: '\u00B1'
 | 
						|
		, sup2: '\u00B2'
 | 
						|
		, sup3: '\u00B3'
 | 
						|
		, micro: '\u00B5'
 | 
						|
		, para: '\u00B6'
 | 
						|
	};
 | 
						|
 | 
						|
 | 
						|
	function rpEntities(s, d, x, z) {
 | 
						|
		if (z) {
 | 
						|
			return xharsQuot[z] || '\x01';
 | 
						|
		};
 | 
						|
 | 
						|
		if (d) {
 | 
						|
			return String.fromCharCode(d);
 | 
						|
		};
 | 
						|
 | 
						|
		return String.fromCharCode(parseInt(x, 16));
 | 
						|
	};
 | 
						|
 | 
						|
	function unEntities(s, i) {
 | 
						|
		s = String(s);
 | 
						|
		if (s.length > 3 && s.indexOf('&') !== -1) {
 | 
						|
			if (s.indexOf('>') !== -1) s = s.replace(/>/g, '>');
 | 
						|
			if (s.indexOf('<') !== -1) s = s.replace(/</g, '<');
 | 
						|
			if (s.indexOf('"') !== -1) s = s.replace(/"/g, '"');
 | 
						|
 | 
						|
			if (s.indexOf('&') !== -1) {
 | 
						|
				s = s.replace(/&#(\d+);|&#x([0123456789abcdef]+);|&(\w+);/ig, rpEntities);
 | 
						|
			};
 | 
						|
		};
 | 
						|
 | 
						|
		return s;
 | 
						|
	};
 | 
						|
 | 
						|
	var attr_string = ''; // строка атрибутов
 | 
						|
	var attr_posstart = 0; // 
 | 
						|
	var attr_res; // закешированный результат разбора атрибутов , null - разбор не проводился, object - хеш атрибутов, true - нет атрибутов, false - невалидный xml
 | 
						|
 | 
						|
	/*
 | 
						|
		парсит атрибуты по требованию. Важно! - функция не генерирует исключения.
 | 
						|
 | 
						|
		если была ошибка разбора возврашается false
 | 
						|
		если атрибутов нет и разбор удачен то возврашается true
 | 
						|
		если есть атрибуты то возврашается обьект(хеш)
 | 
						|
	*/
 | 
						|
 | 
						|
	var RGX_ATTR_NAME = /[^\w:-]+/g;
 | 
						|
 | 
						|
	function getAttrs() {
 | 
						|
		if (attr_res !== null) {
 | 
						|
			return attr_res;
 | 
						|
		};
 | 
						|
 | 
						|
		/*
 | 
						|
		if (xxtest !== u && attr_string.indexOf(xxtest) === -1) {
 | 
						|
			/ *
 | 
						|
				// для ускорения 
 | 
						|
				if (getAttrs('html').type == 'html') {
 | 
						|
					...
 | 
						|
				};
 | 
						|
			* /
 | 
						|
			return true;
 | 
						|
		};
 | 
						|
		*/
 | 
						|
 | 
						|
		var u
 | 
						|
		, res = {}
 | 
						|
		, s = attr_string
 | 
						|
		, i = attr_posstart
 | 
						|
		, l = s.length
 | 
						|
		, attr_list = hasSurmiseNS ? [] : false
 | 
						|
		, name, value = ''
 | 
						|
		, ok = false
 | 
						|
		, j, w, nn, n
 | 
						|
		, hasNewMatrix
 | 
						|
		, alias, newalias
 | 
						|
		; 
 | 
						|
 | 
						|
 | 
						|
		aa: 
 | 
						|
		for(; i < l; i++) {
 | 
						|
			w = s.charCodeAt(i);
 | 
						|
 | 
						|
			if (w===32 || (w<14 && w > 8) ) { // \f\n\r\t\v
 | 
						|
				continue
 | 
						|
			};
 | 
						|
 | 
						|
			if (w < 65 || w >122 || (w>90 && w<97) ) { // ожидаем символ
 | 
						|
				//console.log('error attr 1')
 | 
						|
				return attr_res = false; // error. invalid char
 | 
						|
			};
 | 
						|
 | 
						|
			for(j = i + 1; j < l; j++) { // проверяем все символы имени атрибута 
 | 
						|
				w = s.charCodeAt(j);
 | 
						|
 | 
						|
				if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 45 || w === 95 || w === 46 /* https://github.com/telerik/xPlatCore/issues/179 */) {
 | 
						|
					continue;
 | 
						|
				};
 | 
						|
 | 
						|
 | 
						|
				if (w !== 61) { // "=" == 61
 | 
						|
					//console.log('error 2');
 | 
						|
					return attr_res = false; // error. invalid char
 | 
						|
				};
 | 
						|
 | 
						|
				break;
 | 
						|
			};
 | 
						|
 | 
						|
			name = s.substring(i, j);
 | 
						|
			ok = true;
 | 
						|
 | 
						|
			if (name === 'xmlns:xmlns') {
 | 
						|
				//console.log('error 6')
 | 
						|
				return attr_res = false; // error. invalid name
 | 
						|
			};
 | 
						|
 | 
						|
			w = s.charCodeAt(j+1);
 | 
						|
 | 
						|
			if (w === 34) {  // '"'
 | 
						|
				j = s.indexOf('"', i = j+2 );
 | 
						|
 | 
						|
			} else {
 | 
						|
				if (w === 39) {
 | 
						|
					j = s.indexOf('\'', i = j+2 );
 | 
						|
 | 
						|
				} else {  // "'"
 | 
						|
					//console.log('error 3')
 | 
						|
					return attr_res = false; // error. invalid char
 | 
						|
				};
 | 
						|
			};
 | 
						|
 | 
						|
			if (j === -1) {
 | 
						|
				//console.log('error 4')
 | 
						|
				return attr_res = false; // error. invalid char
 | 
						|
			};
 | 
						|
 | 
						|
 | 
						|
			if (j+1 < l) {
 | 
						|
				w = s.charCodeAt(j+1);
 | 
						|
 | 
						|
				if (w > 32 || w < 9 || (w<32 && w>13)) {
 | 
						|
					// error. invalid char
 | 
						|
					//console.log('error 5')
 | 
						|
					return attr_res = false;
 | 
						|
				};
 | 
						|
			};
 | 
						|
 | 
						|
 | 
						|
			value = s.substring(i, j);
 | 
						|
			i = j + 1; // след. семвол уже проверен потому проверять нужно следуюший
 | 
						|
 | 
						|
			if (isNamespace) { // 
 | 
						|
				if (hasSurmiseNS) {
 | 
						|
					// есть подозрение что в атрибутах присутствует xmlns
 | 
						|
 | 
						|
					if (newalias = name === 'xmlns' ? 'xmlns' : name.charCodeAt(0) === 120 && name.substr(0, 6) === 'xmlns:' && name.substr(6) ) {
 | 
						|
						alias = useNS[unEntities(value)];
 | 
						|
 | 
						|
						if (alias) {
 | 
						|
							if (nsmatrix[newalias] !== alias) {
 | 
						|
								if (!hasNewMatrix) {
 | 
						|
									hasNewMatrix = true;
 | 
						|
									nn = {}; for (n in nsmatrix) nn[n] = nsmatrix[n];
 | 
						|
									nsmatrix = nn;
 | 
						|
								};
 | 
						|
 | 
						|
								nsmatrix[newalias] = alias;
 | 
						|
							};
 | 
						|
						} else {
 | 
						|
							if (nsmatrix[newalias]) {
 | 
						|
								if (!hasNewMatrix) {
 | 
						|
									hasNewMatrix = true;
 | 
						|
									nn = {}; for (n in nsmatrix) nn[n] = nsmatrix[n];
 | 
						|
									nsmatrix = nn;
 | 
						|
								};
 | 
						|
 | 
						|
								nsmatrix[newalias] = false;
 | 
						|
							};
 | 
						|
						};
 | 
						|
 | 
						|
						res[name] = value;
 | 
						|
						continue;
 | 
						|
					};
 | 
						|
 | 
						|
					attr_list.push(name, value);
 | 
						|
					continue;
 | 
						|
				};
 | 
						|
 | 
						|
				w = name.length;
 | 
						|
				while(--w) {
 | 
						|
					if (name.charCodeAt(w) === 58) { // ':'
 | 
						|
						if (w = nsmatrix[name.substring(0, w)] ) {
 | 
						|
							res[w + name.substr(w)] = value;
 | 
						|
						};
 | 
						|
						continue aa;
 | 
						|
 | 
						|
						// 'xml:base' ???
 | 
						|
					};
 | 
						|
				};
 | 
						|
			};
 | 
						|
 | 
						|
			res[name] = value;
 | 
						|
		};
 | 
						|
 | 
						|
 | 
						|
		if (!ok) {
 | 
						|
			return attr_res = true;  // атрибутов нет, ошибок тоже нет
 | 
						|
		};
 | 
						|
		
 | 
						|
 | 
						|
		if (hasSurmiseNS)  {
 | 
						|
			bb: 
 | 
						|
 | 
						|
			for (i = 0, l = attr_list.length; i < l; i++) {
 | 
						|
				name = attr_list[i++];
 | 
						|
 | 
						|
				w = name.length;
 | 
						|
				while(--w) { // name.indexOf(':')
 | 
						|
					if (name.charCodeAt(w) === 58) { // ':'
 | 
						|
						if (w = nsmatrix[name.substring(0, w)]) {
 | 
						|
							res[w + name.substr(w)] = attr_list[i];
 | 
						|
						};
 | 
						|
						continue bb;
 | 
						|
						break;
 | 
						|
					};
 | 
						|
				};
 | 
						|
 | 
						|
				res[name] = attr_list[i];
 | 
						|
			};
 | 
						|
		};
 | 
						|
 | 
						|
		return attr_res = res;
 | 
						|
	};
 | 
						|
 | 
						|
 | 
						|
	// xml - string
 | 
						|
	function parse(xml) {
 | 
						|
		var u
 | 
						|
		, xml = String(xml)
 | 
						|
		, nodestack = []
 | 
						|
		, stacknsmatrix = []
 | 
						|
		//, string_node
 | 
						|
		, elem
 | 
						|
		, tagend = false
 | 
						|
		, tagstart = false
 | 
						|
		, j = 0, i = 0
 | 
						|
		, x, y, q, w
 | 
						|
		, xmlns
 | 
						|
		, stopIndex = 0
 | 
						|
		, stop // используется при разборе "namespace" . если встретился неизвестное пространство то события не генерируются
 | 
						|
		, _nsmatrix
 | 
						|
		, ok
 | 
						|
		;
 | 
						|
 | 
						|
		function getStringNode() {
 | 
						|
			return xml.substring(i, j+1)
 | 
						|
		};
 | 
						|
 | 
						|
		while(j !== -1) {
 | 
						|
			stop = stopIndex > 0;
 | 
						|
 | 
						|
			if (xml.charCodeAt(j) === 60) { // "<"
 | 
						|
				i = j;
 | 
						|
			} else {
 | 
						|
				i = xml.indexOf('<', j);
 | 
						|
			};
 | 
						|
 | 
						|
			if (i === -1) { // конец разбора
 | 
						|
 | 
						|
				if (nodestack.length) {
 | 
						|
					onError('end file');
 | 
						|
					return;
 | 
						|
				};
 | 
						|
 | 
						|
				return;
 | 
						|
			};
 | 
						|
 | 
						|
			if (j !== i && !stop) {
 | 
						|
				ok = onTextNode(xml.substring(j, i), unEntities);
 | 
						|
				if (ok === false) return;
 | 
						|
			};
 | 
						|
 | 
						|
			w = xml.charCodeAt(i+1);
 | 
						|
 | 
						|
			if (w === 33) { // "!"
 | 
						|
				w = xml.charCodeAt(i+2);
 | 
						|
				if (w === 91 && xml.substr(i+3, 6) === 'CDATA[') { // 91 == "["
 | 
						|
					j = xml.indexOf(']]>', i);
 | 
						|
					if (j === -1) {
 | 
						|
						onError('cdata');
 | 
						|
						return;
 | 
						|
					};
 | 
						|
					
 | 
						|
					//x = xml.substring(i+9, j);
 | 
						|
					if (!stop) {
 | 
						|
						ok = onCDATA(xml.substring(i+9, j), false);
 | 
						|
						if (ok === false) return;
 | 
						|
					};
 | 
						|
					
 | 
						|
 | 
						|
					j += 3;
 | 
						|
					continue;
 | 
						|
				};
 | 
						|
				
 | 
						|
 | 
						|
				if (w === 45 && xml.charCodeAt(i+3) === 45) { // 45 == "-"
 | 
						|
					j = xml.indexOf('-->', i);
 | 
						|
					if (j === -1) {
 | 
						|
						onError('expected -->');
 | 
						|
						return;
 | 
						|
					};
 | 
						|
 | 
						|
 | 
						|
					if (is_onComment && !stop) {
 | 
						|
						ok = onComment(xml.substring(i+4, j), unEntities);
 | 
						|
						if (ok === false) return;
 | 
						|
					};
 | 
						|
 | 
						|
					j += 3;
 | 
						|
					continue;
 | 
						|
				};
 | 
						|
 | 
						|
				j = xml.indexOf('>', i+1);
 | 
						|
				if (j === -1) {
 | 
						|
					onError('expected ">"');
 | 
						|
					return;
 | 
						|
				};
 | 
						|
 | 
						|
				if (is_onAttention && !stop) {
 | 
						|
					ok = onAttention(xml.substring(i, j+1), unEntities);
 | 
						|
					if (ok === false) return;
 | 
						|
				};
 | 
						|
 | 
						|
				j += 1;
 | 
						|
				continue;
 | 
						|
 | 
						|
			} else {
 | 
						|
				if (w === 63) { // "?"
 | 
						|
					j = xml.indexOf('?>', i);
 | 
						|
					if (j === -1) { // error
 | 
						|
						onError('...?>');
 | 
						|
						return;
 | 
						|
					};
 | 
						|
					
 | 
						|
					if (is_onQuestion) {
 | 
						|
						ok = onQuestion(xml.substring(i, j+2));
 | 
						|
						if (ok === false) return;
 | 
						|
					};
 | 
						|
 | 
						|
					j += 2;
 | 
						|
					continue;
 | 
						|
				};
 | 
						|
			};
 | 
						|
 | 
						|
			j = xml.indexOf('>', i+1);
 | 
						|
 | 
						|
			if (j == -1) { // error 
 | 
						|
				onError('...>');
 | 
						|
				return;
 | 
						|
			};
 | 
						|
 | 
						|
			attr_res = true; // атрибутов нет
 | 
						|
 | 
						|
			//if (xml.charCodeAt(i+1) === 47) { // </...
 | 
						|
			if (w === 47) { // </...
 | 
						|
				tagstart = false;
 | 
						|
				tagend = true;
 | 
						|
 | 
						|
				// проверяем что должен быть закрыт тотже тег что и открывался
 | 
						|
				x = elem = nodestack.pop();
 | 
						|
				q = i + 2 + x.length;
 | 
						|
 | 
						|
				//console.log()
 | 
						|
				if (xml.substring(i+2, q) !== x) {
 | 
						|
					onError('close tagname');
 | 
						|
					return;
 | 
						|
				};
 | 
						|
 | 
						|
				// проверим что в закрываюшем теге нет лишнего
 | 
						|
				for(; q < j; q++) {
 | 
						|
					w = xml.charCodeAt(q);
 | 
						|
 | 
						|
					if (w===32 || (w > 8 && w<14) ) {  // \f\n\r\t\v пробел
 | 
						|
						continue;
 | 
						|
					};
 | 
						|
 | 
						|
					onError('close tag');
 | 
						|
					return;
 | 
						|
				};
 | 
						|
 | 
						|
			} else {
 | 
						|
				if (xml.charCodeAt(j-1) ===  47) { // .../>
 | 
						|
					x = elem = xml.substring(i+1, j-1);
 | 
						|
 | 
						|
					tagstart = true;
 | 
						|
					tagend = true;
 | 
						|
				} else {
 | 
						|
					x = elem = xml.substring(i+1, j);
 | 
						|
 | 
						|
					tagstart = true;
 | 
						|
					tagend = false;
 | 
						|
				};
 | 
						|
 | 
						|
				if ( !(w > 96  && w < 123 || w > 64 && w <91) ) {
 | 
						|
					onError('first char nodeName');
 | 
						|
					return;
 | 
						|
				};
 | 
						|
 | 
						|
				for(q = 1, y = x.length; q < y; q++) {
 | 
						|
					w = x.charCodeAt(q);
 | 
						|
 | 
						|
					if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 45 || w === 95 || w === 46 /* https://github.com/telerik/xPlatCore/issues/179 */) {
 | 
						|
						continue;
 | 
						|
					};
 | 
						|
 | 
						|
					if (w===32 || (w<14 && w > 8)) { // \f\n\r\t\v пробел
 | 
						|
						elem = x.substring(0, q)
 | 
						|
						attr_res = null; // возможно есть атирибуты
 | 
						|
						break;
 | 
						|
					};
 | 
						|
 | 
						|
					onError('invalid nodeName');
 | 
						|
					return;
 | 
						|
				};
 | 
						|
 | 
						|
				if (!tagend) {
 | 
						|
					nodestack.push(elem);
 | 
						|
				};
 | 
						|
			};
 | 
						|
 | 
						|
 | 
						|
			if (isNamespace) {
 | 
						|
				if (stop) {
 | 
						|
					if (tagend) {
 | 
						|
						if (!tagstart) {
 | 
						|
							if (--stopIndex === 0) {
 | 
						|
								nsmatrix = stacknsmatrix.pop();
 | 
						|
							};
 | 
						|
						};
 | 
						|
 | 
						|
					} else {
 | 
						|
						stopIndex += 1;
 | 
						|
					};
 | 
						|
 | 
						|
 | 
						|
					j += 1;
 | 
						|
					continue;
 | 
						|
				};
 | 
						|
 | 
						|
				_nsmatrix = nsmatrix;
 | 
						|
 | 
						|
				if (!tagend) {
 | 
						|
					stacknsmatrix.push(nsmatrix);
 | 
						|
					
 | 
						|
					if (attr_res !== true) {
 | 
						|
						if (hasSurmiseNS = x.indexOf('xmlns', q) !== -1) {
 | 
						|
							attr_string = x;
 | 
						|
							attr_posstart = q;
 | 
						|
 | 
						|
							getAttrs();
 | 
						|
 | 
						|
							hasSurmiseNS = false;
 | 
						|
						};
 | 
						|
					};
 | 
						|
				};
 | 
						|
 | 
						|
 | 
						|
				w = elem.indexOf(':'); 
 | 
						|
				if (w !== -1) {
 | 
						|
					xmlns = nsmatrix[elem.substring(0, w)];
 | 
						|
					elem = elem.substr(w+1);
 | 
						|
					
 | 
						|
					
 | 
						|
				} else {
 | 
						|
					xmlns = nsmatrix.xmlns;
 | 
						|
				};
 | 
						|
 | 
						|
				
 | 
						|
				if (!xmlns) {
 | 
						|
					if (tagend) {
 | 
						|
						if (tagstart) {
 | 
						|
							nsmatrix = _nsmatrix;
 | 
						|
						} else {
 | 
						|
							nsmatrix = stacknsmatrix.pop();
 | 
						|
						};
 | 
						|
					} else {
 | 
						|
						stopIndex = 1; // первый элемент для которого не определено пространство имен 
 | 
						|
						attr_res = true;
 | 
						|
					};
 | 
						|
 | 
						|
					j += 1;
 | 
						|
					continue;
 | 
						|
				};
 | 
						|
 | 
						|
				elem = xmlns + ':' + elem;
 | 
						|
			};
 | 
						|
 | 
						|
			//string_node = xml.substring(i, j+1); // текст ноды как есть
 | 
						|
			
 | 
						|
 | 
						|
			if (tagstart) { // is_onStartNode
 | 
						|
				attr_string = x;
 | 
						|
				attr_posstart = q;
 | 
						|
 | 
						|
				ok = onStartNode(elem, getAttrs, unEntities, tagend
 | 
						|
					, getStringNode
 | 
						|
				);
 | 
						|
 | 
						|
				if (ok === false) {
 | 
						|
					return;
 | 
						|
				};
 | 
						|
 | 
						|
				attr_res = true;
 | 
						|
			};
 | 
						|
 | 
						|
			if (tagend) {
 | 
						|
				ok = onEndNode(elem, unEntities, tagstart
 | 
						|
					, getStringNode
 | 
						|
				);
 | 
						|
 | 
						|
				if (ok === false) {
 | 
						|
					return;
 | 
						|
				};
 | 
						|
 | 
						|
				if (isNamespace) {
 | 
						|
					if (tagstart) {
 | 
						|
						nsmatrix = _nsmatrix;
 | 
						|
					} else {
 | 
						|
						nsmatrix = stacknsmatrix.pop();
 | 
						|
					};
 | 
						|
				};
 | 
						|
			};
 | 
						|
 | 
						|
			j += 1;
 | 
						|
		}; 
 | 
						|
	};
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 |