现在的位置: 首页 > 综合 > 正文

处理xml(html)中的空格

2012年10月08日 ⁄ 综合 ⁄ 共 3653字 ⁄ 字号 评论关闭

    xml文档(包括html)是从一个独立的根结点开始,它包含指向子节点的指针。每一个子节点都包含指针指向它的父节点、相邻节点和子节点。标准dom中,dom指针不仅可以指向元素,也可以指向文本节点。  请看以下html代码:

<body>
    
<h1>DOM简介</h1>
    <p id="test">DOM是一个表达XML文档的标准</p>
    <p>你随处可见dom的身影</p>
</body>

    我想获得id为test的p元素的下一个p元素,可能理所当然的认为用document.getElementById('test').nextSibling就能获得。其实不然。在ie中确实能够获得你想要的,而在firefox、Opera9和Safari中你只能获得一个空格。《精通javascript》上提供了一个函数,用于处理xm中的这些空格,其作用原理就是找出文本节点,并删除这些节点,以达到删除这些空格的目的。

function cleanWhitespace(element){
    
//如果不提供参数,则处理整个HTML文档
    element = element || document;
    
//使用第一个子节点作为开始指针
    var cur = element.firstChild;
    
    
//一直到没有子节点为止
    while (cur != null){
        
//如果节点为文本节点,应且包含空格
        if ( cur.nodeType == && ! /\S/.test(cur.nodeValue)){
            
//删除这个文本节点
            element.removeChild( cur );
            
            
//否则,它就是一个元素
        }
 else if (cur.nodeType == 1){
            
//递归整个文档
            cleanWhitespace( cur );
        }

        
        cur 
= cur.nextSibling;//遍历子节点
    }

}

    正如书中作者所提到的,该函数的缺点是必须遍历每个DOM元素和文本节点,会严重降低网站的加载速度。每一次为文档注入新的html,都需要重新扫描dom中的新内容,确保没有增加新的有空格填充的文本节点。
    在这里,不妨做一个简单的判断,如果id为test的p元素的下一个节点是文本节点(即nodeType为3)的话,就继续往下遍历。如果是元素节点的话,则不需要往下遍历。代码如下:

var testP = document.getElementById('test'); 
    
var reason = testP.nextSibling;
    
if(reason.nodeType == 1){
        alert(reason.innerHTML);
    }
 else if(reason.nodeType == 3){
        alert(reason.nextSibling.innerHTML);
    }
    
}

    对非IE浏览器,可以用常量来表明不同的DOM节点类型。document.ELEMENT_NODE、document.TEXT_NODE、document.DOCUMENT_NODE代表元素节点、文本节点、文档节点。
    最后,利用数组写了一个函数,能够有效的处理dom中的空格,其原理就是将一个元素的的父元素找出来,然后通过它父元素的childNodes属性找出该元素的所有兄弟元素。遍历该元素和它的兄弟元素,将所有元素节点放在一个数组里。这样调用这个数组,就只有元素节点而没有文本节点,也就没有了讨厌的空格。
    该函数如下:

function cleanWhitespaces(elem){
    
var elem = elem || document;
    
var parentElem = elem.parentNode; 
    
var childElem = parentElem.childNodes;
    
var childElemArray = new Array;
    
for (var i=0; i<childElem.length; i++){
        
if (childElem[i].nodeType==1){
            childElemArray.push(childElem[i]);
        }

    }

    
return childElemArray;
}

最后完整的一个示例如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DOMWhitespace</title>
<script type="text/javascript">
window.onload 
= function(){
    
var testP = document.getElementById('test');
    cleanWhitespaces(testP);
    alert(testP.innerHTML);
}

function cleanWhitespaces(elem){
    
var elem = elem || document;
    
var parentElem = elem.parentNode; 
    
var childElem = parentElem.childNodes;
    
var childElemArray = new Array;
    
for (var i=0; i<childElem.length; i++){
        
if (childElem[i].nodeType==1){
            childElemArray.push(childElem[i]);
        }

    }

    
return childElemArray;
}
 
</script>
</head>

<body>
    
<h1>DOM简介</h1>
    <p id="test">dom的广泛使用是有道理的,以下是一些原因:</p>
    <p>你随处可见dom的身影</p>
    <ul>
        
<li><a href="" title="">link1</a></li>
        
<li><a href="" title="">link2</a></li>
    
</ul>
</body>
</html>

function removeWhitespace(xml){
    
var loopIndex;
    
    
for (loopIndex = 0; loopIndex < xml.childNodes.length; loopIndex++){
        
var currentNode = xml.childNodes[loopIndex];
        
if (currentNode.nodeType == 1){
            removeWhitespace(currentNode);
        }

        
        
if (((/^\s+$/.test(currentNode.nodeValue))) &&(currentNode.nodeType == 3)){
            xml.removeChild(xml.childNodes[loopIndex
--]);
        }

    }

}

 

    原理是对元素的所有的子节点做一个遍历。然后做一个判断,如果是子元素节点(nodeType = 1),则遍历该子元素的所有的子节点,用递归检查是否包含空白节点;如果处理的子节点是文本节点(nodeType = 3),则检查是否是纯粹的空白节点,如果是,就将它从xml对象中删除。
    这个函数,应该和上面我自己写的函数作用和使用方法基本一样。非常不错的函数。

  本博文发布3天后,我在《ajax宝典》上又看到了一个用于处理xml中空格的好函数。原理还是一样的,代码如下:

抱歉!评论已关闭.