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;
}