Spry源码笔记——自动将Document转换成JSON格式

在运用Ajax中,有很多操作都是将获得的XML文档转换成JSON格式的,方便JavaScript操作。在Adobe Spry源码里发现了有专门进行这种转换的函数,大大减轻了工作量。我把它提取出来,做了一些改动。

首先创建一个函数,用于判断一个节点是否只含有文本内容:

/**
 * 判断该节点是否只包含文本节点
 * @param {Object} node 用于判断的 节点
 * @return {Boolean} 如果只包含文本内容为 true
 */
var nodeHasValue = function(node){
	if(node){
		var child = node.firstChild;
		if (child && child.nextSibling === null && (child.nodeType === 3 /* Node.TEXT_NODE */ || child.nodeType === 4 /* CDATA_SECTION_NODE */))
			return true;
	}
	return false;
}

下面是nodeToObject函数,是整个功能模块的核心,它的功能是把节点(node)转换成JSON格式:

/**
 * 把 Node 转换成 JSON 格式
 * @param {Object} node 用于转换的 节点
 * @requires EYoo.XML.nodeHasValue 判断该节点是否只包含文本节点
 * @return {Object} obj JSON 格式的信息
*/
var nodeToObject = function(node){
	if (!node)
		return null;
	var obj = {};
	// Add all attributes as properties of the object.
	for (var i = 0; i < node.attributes.length; i++){
		var attr = node.attributes[i];
		var attrName = "@" + attr.name;
		obj[attrName] = attr.value;
	}

	var child;
	// 判断该节点是否只包含文本节点
	if(nodeHasValue(node)){
		try{
			child = node.firstChild;
			if (child.nodeType == 3 /* TEXT_NODE */){
				obj[child.nodeName] = child.data;
			}else if (child.nodeType == 4 /* CDATA_SECTION_NODE */){
				obj[child.nodeName] = child.data;
			}
		}catch(e){
			throw("nodeToObject() exception caught: " + e + "\n");
		}

	}else{
		// 如果不是文本节点
		child = node.firstChild;
		while(child){
			if (child.nodeType == 1 /* Node.ELEMENT_NODE */){
				var isArray = false;
				var tagName = child.nodeName;

				// 如果已经存在该节点信息了,则转换成 Array 类型
				if(obj[tagName]){
					if(obj[tagName].constructor != Array){
						var curValue = obj[tagName];
						obj[tagName] = new Array;
						obj[tagName].push(curValue);
					}
					isArray = true;
				}
				var childObj = nodeToObject(child);

				if (isArray)
					obj[tagName].push(childObj);
				else
					obj[tagName] = childObj;
			}
			child = child.nextSibling;
		}
	}
	return obj;
}

最后就是documentToObject函数,它的功能是把整个XML文档转换成JSON格式:

var documentToObject = function(xmlDoc){
	var obj = null;
	if(xmlDoc && xmlDoc.firstChild){
		var child = xmlDoc.firstChild;
		while(child){
			if(child.nodeType == 1 /* Node.ELEMENT_NODE */){
				obj = {};
				obj[child.nodeName] = nodeToObject(child);
				break;
			}
			child = child.nextSibling;
		}
	}
	return obj;
}

另外还有一个encodeEntities函数,它的功能是对文本内容进行转义,防止在使用innerHTML方法时会出现错误:

var encodeEntities = function(str){
	if (str && str.search(/[&<>"]/) != -1){
		str = str.replace(/&/g, "&amp;");
		str = str.replace(/</g, "&lt;");
		str = str.replace(/>/g, "&gt;");
		str = str.replace(/"/g, "&quot;");
	}
	return str;
}
此条目发表在 前端 分类目录,贴了 , , , , 标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已被标记为 *

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>