Chinaunix首页 | 论坛 | 博客
  • 博客访问: 101417
  • 博文数量: 1
  • 博客积分: 1430
  • 博客等级: 上尉
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2005-04-07 20:44
文章分类

全部博文(1)

文章存档

2008年(1)

我的朋友

分类: 系统运维

2008-04-03 15:53:53

一年前发过一篇关于ajaxslt的文章,期间用ajaxslt做过一个产品,感觉ajaxslt有各种好处,但是奈何js效率有限,最终还是回到使用浏览器自己的DOM实现上来。
重新学习浏览器DOM实现的过程中写了几个函数,在IE和FireFox上测试通过。
从效率测试上来看,这个代码比ajaxslt快差不多两个数量级,但问题就是浏览器的依赖性问题,好在我的目标仅仅是兼容IE6及以上版本、FireFox2及以上版本,问题不大。


// author: yangyi (yangyi.cn.gz@gmail.com)


// Based on < (copy from ajaxslt)

var DOM_ELEMENT_NODE = 1;
var DOM_ATTRIBUTE_NODE = 2;
var DOM_TEXT_NODE = 3;
var DOM_CDATA_SECTION_NODE = 4;
var DOM_ENTITY_REFERENCE_NODE = 5;
var DOM_ENTITY_NODE = 6;
var DOM_PROCESSING_INSTRUCTION_NODE = 7;
var DOM_COMMENT_NODE = 8;
var DOM_DOCUMENT_NODE = 9;
var DOM_DOCUMENT_TYPE_NODE = 10;
var DOM_DOCUMENT_FRAGMENT_NODE = 11;
var DOM_NOTATION_NODE = 12;

/**
 * http://developer.mozilla.org/en/docs/DOMParser
 * 接受一段xml,解析成为xml document对象
 * 调用时可用try{}catch(e){}捕捉错误,错误对象具有parser xml message属性
 * @param {String} xml string
 * @return {Object} xml document object
 */

function xmlDocument(/* String */xmlString){
    var doc = null;

    if (window.ActiveXObject){
        var ActiveIds = ['MSXML2.XMLDOM', 'Microsoft.XMLDOM', 'MSXML.XMLDOM', 'MSXML3.XMLDOM'];
        for (var len = ActiveIds.length, i = 0; i < len; i++){
            var id = ActiveIds[i];
            try{
                var doc = new ActiveXObject(id);
                doc.async = false;
                doc.setProperty('SelectionLanguage', 'XPath');
                doc.loadXML(xmlString);
                break;
            }catch (e){}finally{
                if (doc && doc.parseError && doc.parseError.errorCode != 0){
                    throw {parser:'MSXML', message:doc.parseError.reason, xml:xmlString, func:'xmlDocument'};
                }
            }
        }
    }else if (typeof DOMParser != 'undefined'){
        var parser = new DOMParser();
        var doc = parser.parseFromString(xmlString, 'text/xml');
        if (doc.documentElement.nodeName == 'parsererror'){
            throw {parser:'DOMParser', message:doc.documentElement.firstChild.nodeValue, xml:xmlString, func:'xmlDocument'};
        }
    }else{ return false; }

    return doc;
}

/**
 * 获取指定节点或文档对象的xml内容
 * port from ajaxslt xmlText()
 * @param {Object} xml DOM Node or xml Document
 * @return {String} xml string
 */

function xmlText(/* Document|Element */node){
    if (typeof node == 'string'){ return node; }

    if (node.innerXML){
        return node.innerXML;
    }else if (node.xml){
        return node.xml;
    }else if (typeof XMLSerializer != 'undefined'){
        return (new XMLSerializer()).serializeToString(node);
    }else{ return false; }
}

/**
 * 获取所有节点的内容
 * port from ajaxslt xmlValue()
 * @param {Object} xml DOM Node or xml Document
 * @return {String}
 */

function xmlValue(/* Document|Element */node){
    var val = '';
    if (node.nodeType == DOM_TEXT_NODE ||
        node.nodeType == DOM_CDATA_SECTION_NODE ||
        node.nodeType == DOM_ATTRIBUTE_NODE){
        val += node.nodeValue;
    }else if (node.nodeType == DOM_ELEMENT_NODE ||
              node.nodeType == DOM_DOCUMENT_NODE ||
              node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE){
        for (var len = node.childNodes.length, i = 0; i < len; i++){
            val += arguments.callee(node.childNodes[i]);
        }
    }
    return val;
}

/**
 * 获取节点属性,以对象形式返回
 * @param {Object}
 * @return {Object}
 */

function xmlGetAttributes(/* Element */node){
    var result = {};
    var nodeMap = node.attributes;
    if (nodeMap){
        for (var len = nodeMap.length, i = 0; i < len; i++){
            var aNode = nodeMap.item(i);
            result[aNode.nodeName] = aNode.nodeValue;
        }
    }
    return result;
}

/**
 * 设置节点属性
 * @param {Object} xml DOM Node
 * @param {Object} attribute data as object type
 * @return {Void}
 */

function xmlSetAttributes(/* Element */node, /* Object */attributes){
    var attributes = attributes || {};
    for (key in attributes){
        node.setAttribute(key, attributes[key]);
    }
}

/**
 * 使用xpath在xml树中查询
 * http://developer.mozilla.org/en/docs/Introduction_to_using_XPath_in_JavaScript
 * @param {Object} xml Document or xml DOM Node
 * @param {String} xpath query string
 * @param {Boolean} if set true, only return first result node
 * @return {Mixed} return array include all nodes or first node
 */

function xpathSelectNodes(/* Document|Element */root, /* String */query, /* Boolean */returnFirst){
    if (window.ActiveXObject){
        return returnFirst ? root.selectSingleNode(query) : root.selectNodes(query);
    }else if (document.evaluate){
        /**
         * DOMParser的return type有ordered和unordered两种
         * ordered会按照树中间的顺序排列结果,unordered不一定
         * 另外还有一种snapshots的,这种结果是树节点的一个clone
         * 也就是说,如果操作结果节点,原来的节点不会有改变
         * 这里使用非clone方式
         */

        var returnType = returnFirst ? XPathResult.FIRST_ORDERED_NODE_TYPE : XPathResult.ORDERED_NODE_ITERATOR_TYPE;
        var doc = (root.nodeType == DOM_DOCUMENT_NODE) ? root : root.ownerDocument;
        var root = (root.nodeType == DOM_DOCUMENT_NODE) ? root.documentElement : root;
        var result = doc.evaluate(query, root, null, returnType, null);

        if (returnFirst){
            var nodes = result.singleNodeValue;
        }else{
            var nextNode = result.iterateNext();
            var nodes = [];
            while (nextNode){
                nodes.push(nextNode);
                nextNode = result.iterateNext();
            }
        }
    }
    return nodes;
}

/**
 * http://developer.mozilla.org/en/docs/Transforming_XML_with_XSLT
 * http://developer.mozilla.org/en/docs/Using_the_Mozilla_JavaScript_interface_to_XSL_Transformations
 * @param {Mixed} source xml, xml string or xml Document or xml DOM Node
 * @param {Mixed} xslt style sheet, xml string or xml Document or xml DOM Node
 * @param {Boolean} if set true, return processed xml as Document
 * @return {Mixed} return string or Document
 */

function xsltProcess(/* String|Document|Element */srcDoc, /* String|Document|Element */stylesheet, /* Boolean */returnAsDoc){
    var returnAsDoc = (typeof returnAsDoc == 'undefined') ? false : returnAsDoc;
    try{
        var srcDoc = (typeof srcDoc == 'string') ? xmlDocument(srcDoc) : srcDoc;
        var stylesheet = (typeof stylesheet == 'string') ? xmlDocument(stylesheet) : stylesheet;
    }catch(e){ e.func = 'xsltProcess'; throw e; }

    if (typeof XSLTProcessor != 'undefined'){
        var processor = new XSLTProcessor();
        try{
            processor.importStylesheet(stylesheet);
            var dest = processor.transformToDocument(srcDoc);
            return returnAsDoc ? dest : xmlText(dest);
        }catch(e){ throw {func:'xsltProcess', processor:'XSLTProcessor', xml:xmlText(srcDoc), xslt:xmlText(stylesheet)}; }
    }else if (window.ActiveXObject){
        try{
            var dest = srcDoc.transformNode(stylesheet);
            return returnAsDoc ? xmlDocument(dest) : dest;
        }catch(e){ throw {func:'xsltProcess', processor:'MSXML', xml:xmlText(srcDoc), xslt:xmlText(stylesheet)}; }
    }

    return false;
}

阅读(2503) | 评论(1) | 转发(0) |
0

上一篇:没有了

下一篇:没有了

给主人留下些什么吧!~~

chinaunix网友2008-04-08 13:19:18

COOL !