xml.js

来自「asp的bbs程序」· JavaScript 代码 · 共 212 行

JS
212
字号
/*
  By Hangring
  #2007.11.02#
  ---
  html到xhtml转换
*/
var cXml = {XML:null, MainNode:null};

// 创建xmldom对象
cXml.CreateXmlObject = function() {
    var xmlDom = null;

    if (Browser.IsIE) {
        var Doms = ['MSXML2.DOMDocument','Microsoft.XmlDom'];
        for (var i = 0; i < Doms.length; i++) {
            try {
                xmlDom = new ActiveXObject(Doms[i]);
            }
            catch (e) {}
        }
    }
    else {
        xmlDom = document.implementation.createDocument('', '', null);
    }

    return xmlDom;
};

// 转换为xhtml标准
cXml.HtmlToXHtml = function (html) {
    var xmlDom = this.XML = this.CreateXmlObject();

    this.MainNode = xmlDom.appendChild(xmlDom.createElement('xhtml'));

        //var t1 = new Date().getTime();
    this.AppendChild(this.MainNode, html);
        //var t2 = new Date().getTime();
        //getTime(t2, t1);
};
function getTime (t2, t1) {
    var win = window.open('', 'test');
    win.document.open();
    win.document.write(t2 - t1);
    win.document.close();
}

// 获取xml串
cXml.GetXmlString = function () {
    var xmlStr;
    if (Browser.IsIE) {
        xmlStr = this.MainNode.firstChild.xml;
    }
    else {
        var oSerializer = new XMLSerializer();
        xmlStr = oSerializer.serializeToString(this.MainNode.firstChild);
    }

    ///  [safari error]
    // 替换空格
    xmlStr = xmlStr.replace(/\xA0/g, '&nbsp;');
    // 替换rowspan="1"与colspan="1"
    xmlStr = xmlStr.replace(/(<td[^>]*?)\s*rowspan="?1"?([^>]*?>)/gi, '$1$2');
    xmlStr = xmlStr.replace(/(<td[^>]*?)\s*colspan="?1"?([^>]*?>)/gi, '$1$2');
    
    //xmlStr = xmlStr.replace(/<([^>]+)>&nbsp;<\/\1>/g, '<$1></$1>');

    xmlStr = xmlStr.replace(/^<body\s*[^>]*?>/g, '').replace(/<\/body>$/g, '');
    if (xmlStr == '<br/>' || /^<p>(&nbsp;)?<\/p>$/i.test(xmlStr)) xmlStr = '';

    return xmlStr;
};

// 添加一个子节点
cXml.AppendChild = function (xmlNode, htmlNode) {
    if (! htmlNode) return;

    switch (htmlNode.nodeType) {
        // Node
        case 1:
            var oNodeName = htmlNode.tagName.toLowerCase();

            // ie bug
            if (/\//.test(oNodeName) || /^\s*$/.test(oNodeName)) return;

            // <--- 效率低下
            /*
            // 排除不允许标签,清除空内容标签
            var isNotAllowTag = Config.NotAllowTag().test(oNodeName);
            if (isNotAllowTag) {
                this.AppendChildNodes(xmlNode, htmlNode);
                return;
            }
            */

            // 排除非允许的空元素
            var isSpace = false;
            if (!Config.AllowSingleTag.test(oNodeName) && htmlNode.innerHTML.Trim() == '') {
                if (Config.NotInnerHTMLTag.test(oNodeName)) return;
                isSpace = true;
                htmlNode.innerHTML = oNodeName == 'body' ? '' : '&nbsp;';
            }
            // --->

            // 添加属性
            var oNode = this.CreateNode(oNodeName);
            this.AppendAttributes(oNode, htmlNode);

            // 添加子节点
            oNode = this.AppendChildNodes(oNode, htmlNode);
            if (isSpace) htmlNode.innerHTML = '';

            // 当前节点的xml dom树
            xmlNode.appendChild(oNode);
            break;
        // Text
        case 3:
            var oValue = htmlNode.nodeValue.Trim();
            if (oValue) {
                oValue = oValue.replace(/[ \t\n\r\xA0]/g, '\xA0');
                xmlNode.appendChild(this.XML.createTextNode(oValue));
                //xmlNode.appendChild(this.XML.createCDATASection(oValue));
            }
            break;
        // Comment
        //case 8:
        //    break;
    }
};

// 添加所有子节点
cXml.AppendChildNodes = function (xmlNode, htmlNode) {
    var oNode = htmlNode.firstChild;
    while (oNode) {
        this.AppendChild(xmlNode, oNode);
        oNode = oNode.nextSibling;
    }
    return xmlNode;
};

// 添加属性
cXml.AppendAttributes = function (xmlNode, htmlNode) {
    var attributes = htmlNode.attributes;
    var isImg = xmlNode.nodeName.toLowerCase() == 'img';

    if (htmlNode.className) {
        //alert(htmlNode.width + ' ' + htmlNode.height);
        var oAttr = this.XML.createAttribute('class');
        oAttr.value = htmlNode.className;
        xmlNode.attributes.setNamedItem(oAttr);
    }

    for (var i = 0, len = attributes.length; i < len; i++) {
        var oAttribute = attributes[i];
        var oAttrName = oAttribute.nodeName.toLowerCase();
        if (!/^[a-z_]+[a-z0-9_]*$/i.test(oAttrName)) continue;

/*
        if (isImg && Browser.IsIE && (oAttrName == 'width' || oAttrName == 'height')) {
            continue;
        }  
 */

        // 获取属性值
        var oAttrValue = '';
        // XHTML不支持类似"checked"最小化属性,它必须是checked="checked"
        if (oAttribute.nodeValue === true)
            oAttrValue = oAttrName;
        // 因为IE存在bug,style的nodeValue返回"null",所以需要设置style
        else if (Browser.IsIE && oAttrName == 'style') {
            var s = htmlNode.style.cssText.toLowerCase();
/*
            if (htmlNode.getAttribute('width', 2) && s.indexOf('width') < 0) {
                if (s != '') s += ';';
                s += 'width: ' + htmlNode.getAttribute('width', 2) + 'px;'
                  +  'height: ' + htmlNode.getAttribute('height', 2) + 'px;'
            }
*/
            oAttrValue = s;
        }
        // 获取属性值
        else
            // || oAttribute.nodeValue || '';
            oAttrValue = htmlNode.getAttribute(oAttrName, 2);

        // 创建属性
        var oAttr = this.XML.createAttribute(oAttrName);
        if (oAttrName == 'hspace') continue;
        if (oAttrName == 'alt' ||
            oAttrValue && !Config.NotAllowAttrValue.test(oAttrValue)) {
            ///
            oAttr.value = oAttrValue || '';
        }
        else continue;

        // 排除非允许属性
        if (Config.NotAllowAttr.test(oAttrName)) continue;
        xmlNode.attributes.setNamedItem(oAttr);
    }
};

// 创建节点
cXml.CreateNode = function (nodeName) {
    switch (nodeName) {
        case 'strong':
            nodeName = 'b';
            break;
        case 'em':
            nodeName = 'i';
            break;
    }
    return this.XML.createElement(nodeName);
};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?