自己以前写过一篇文章,是关于dom下xpath的编写,不过那是借助浏览器本身的特性,这次我想用javascrip和正则表达式打造自己的xpath,不多啰嗦,看代码:
function xpath(n,m){
if(//]$/i.test(m)){
var t1=[]
var reg=/^(|//)(.+)/[(.+)/]$/i;
m.match(reg);
if(RegExp.$1=="/"){
var t2=n.childNodes;
for(var i=0;i<t2.length;i++){
if(t2[i].nodeType==1 && t2[i].tagName.toLowerCase()==RegExp.$2)
t1.push(t2[i]);
}
}else{
var t2=n.getElementsByTagName(RegExp.$2);
for(var i=0;i<t2.length;i++){
if(t2[i].nodeType==1)
t1.push(t2[i]);
}
}
if(RegExp.$3.indexOf("='")>-1){
var reg1=/([/w/d]+)(/^=|/~=|/!=|/$=|=)'(.+)'/i;
RegExp.$3.match(reg1);
//alert(RegExp.$3);
switch(RegExp.$2){
case "^=":
for(var i=0;i<t1.length;i++){
if(!(t1[i].getAttribute(RegExp.$1) && t1[i].getAttribute(RegExp.$1).substr(0,RegExp.$3.length)==RegExp.$3)){
t1.splice(i,1);
//alert(i);
i--;
}
}
break;
case "$=":
for(var i=0;i<t1.length;i++){
if(!(t1[i].getAttribute(RegExp.$1) && t1[i].getAttribute(RegExp.$1).substr(t1[i].getAttribute(RegExp.$1).length-RegExp.$3.length,RegExp.$3.length)==RegExp.$3)){
t1.splice(i,1);
i--;
}
}
break;
case "~=":
for(var i=0;i<t1.length;i++){
if(!(t1[i].getAttribute(RegExp.$1) && t1[i].getAttribute(RegExp.$1).indexOf(RegExp.$3)>-1)){
t1.splice(i,1);
i--;
}
}
break;
case "!=":
for(var i=0;i<t1.length;i++){
if(!(t1[i].hasAttribute(RegExp.$1)) || (t1[i].hasAttribute(RegExp.$1) && t1[i].getAttribute(RegExp.$1).indexOf(RegExp.$3)==-1)){
t1.splice(i,1);
i--;
}
}
break;
case "=":
for(var i=0;i<t1.length;i++){
if(!(t1[i].getAttribute(RegExp.$1) && t1[i].getAttribute(RegExp.$1)==RegExp.$3)){
t1.splice(i,1);
i--;
}
}
break;
}
}else{
var reg1=/(!)?([/w/d]+)/i;
RegExp.$3.match(reg1);
if(RegExp.$1){
for (var i = 0; i < t1.length; i++) {
if(t1[i].getAttribute(RegExp.$2)){
t1.splice(i,1);
i--;
}
}
}else{
for (var i = 0; i < t1.length; i++) {
if(!(t1[i].getAttribute(RegExp.$2))){
t1.splice(i,1);
i--;
}
}
}
}
}else{
var t1=[];
var reg=/^(|//)(.+)$/i;
m.match(reg);
if(RegExp.$1=="/"){
var t2=n.childNodes;
for(var i=0;i<t2.length;i++){
if(t2[i].nodeType==1 && t2[i].tagName.toLowerCase()==RegExp.$2)
t1.push(t2[i]);
}
}else{
var t2=n.getElementsByTagName(RegExp.$2);
for(var i=0;i<t2.length;i++){
if(t2[i].nodeType==1)
t1.push(t2[i]);
}
}
}
return t1;
}
主要实现了:
(/|//)tagname([(!)attr(~|!|$|^)(=data)])
的功能。参数n是你要查找的根节点,m是匹配的xpath表达式。
给个例子:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
</head>
<body>
<script src="xpath.js"></script><div id="a"><p>sdfd</p>dsfsd</div>
<script>
alert(xpath(document.body,"//div[id='a']")[0].innerHTML="sx");
</script>
</body>
</html>
主要还是练练手,熟悉下正则表达式,毕竟已经很久没用了,自己的这个xpath还有很多不足,以后自己会多多完善的。
文章有不足之处,还望大家多多指正。